├── .gitignore ├── Docs ├── README.md ├── stm32-secure-patching-bootloader-MultiSegment_rev1_Dec2021.pdf └── stm32-secure-patching-bootloader-QSG_rev4_Mar2023.pdf ├── Include ├── README.md └── stm32_secure_patching_bootloader_interface_v1.4.0.h ├── LICENSE.md ├── Libs ├── B-L072Z-LRWAN1 │ ├── stm32-secure-patching-bootloader-README_B-L072Z-LRWAN1_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_B-L072Z-LRWAN1_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_B-L072Z-LRWAN1_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_B-L072Z-LRWAN1_v1.4.0.bin │ └── stm32-secure-patching-bootloader_B-L072Z-LRWAN1_v1.4.0.bin.asc ├── B-L4S5I-IOT01A │ ├── stm32-secure-patching-bootloader-README_B-L4S5I-IOT01A_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_B-L4S5I-IOT01A_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_B-L4S5I-IOT01A_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_B-L4S5I-IOT01A_v1.4.0.bin │ └── stm32-secure-patching-bootloader_B-L4S5I-IOT01A_v1.4.0.bin.asc ├── DISCO-F469I │ ├── stm32-secure-patching-bootloader-README_DISCO-F469I_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_DISCO-F469I_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_DISCO-F469I_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_DISCO-F469I_v1.4.0.bin │ └── stm32-secure-patching-bootloader_DISCO-F469I_v1.4.0.bin.asc ├── DISCO-F769I │ ├── stm32-secure-patching-bootloader-README_DISCO-F769I_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_DISCO-F769I_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_DISCO-F769I_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_DISCO-F769I_v1.4.0.bin │ └── stm32-secure-patching-bootloader_DISCO-F769I_v1.4.0.bin.asc ├── DISCO-H745I │ ├── stm32-secure-patching-bootloader-README_DISCO-H745I_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_DISCO-H745I_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_DISCO-H745I_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_DISCO-H745I_v1.4.0.bin │ └── stm32-secure-patching-bootloader_DISCO-H745I_v1.4.0.bin.asc ├── DISCO-L476G │ ├── stm32-secure-patching-bootloader-README_DISCO-L476G_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_DISCO-L476G_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_DISCO-L476G_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_DISCO-L476G_v1.4.0.bin │ └── stm32-secure-patching-bootloader_DISCO-L476G_v1.4.0.bin.asc ├── DISCO-L496G │ ├── stm32-secure-patching-bootloader-README_DISCO-L496G_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_DISCO-L496G_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_DISCO-L496G_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_DISCO-L496G_v1.4.0.bin │ └── stm32-secure-patching-bootloader_DISCO-L496G_v1.4.0.bin.asc ├── DISCO-L4R9I │ ├── stm32-secure-patching-bootloader-README_DISCO-L4R9I_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_DISCO-L4R9I_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_DISCO-L4R9I_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_DISCO-L4R9I_v1.4.0.bin │ └── stm32-secure-patching-bootloader_DISCO-L4R9I_v1.4.0.bin.asc ├── DISCO-L562E │ ├── stm32-secure-patching-bootloader-README_DISCO-L562E_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_DISCO-L562E_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_DISCO-L562E_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_DISCO-L562E_v1.4.0.bin │ └── stm32-secure-patching-bootloader_DISCO-L562E_v1.4.0.bin.asc ├── LORA-E5-DEV │ ├── stm32-secure-patching-bootloader-README_LORA-E5-DEV_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_LORA-E5-DEV_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_LORA-E5-DEV_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_LORA-E5-DEV_v1.4.0.bin │ └── stm32-secure-patching-bootloader_LORA-E5-DEV_v1.4.0.bin.asc ├── NUCLEO-F429ZI │ ├── stm32-secure-patching-bootloader-README_NUCLEO-F429ZI_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_NUCLEO-F429ZI_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_NUCLEO-F429ZI_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_NUCLEO-F429ZI_v1.4.0.bin │ └── stm32-secure-patching-bootloader_NUCLEO-F429ZI_v1.4.0.bin.asc ├── NUCLEO-G0B1RE │ ├── stm32-secure-patching-bootloader-README_NUCLEO-G0B1RE_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_NUCLEO-G0B1RE_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_NUCLEO-G0B1RE_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_NUCLEO-G0B1RE_v1.4.0.bin │ └── stm32-secure-patching-bootloader_NUCLEO-G0B1RE_v1.4.0.bin.asc ├── NUCLEO-L073RZ │ ├── stm32-secure-patching-bootloader-README_NUCLEO-L073RZ_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_NUCLEO-L073RZ_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_NUCLEO-L073RZ_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_NUCLEO-L073RZ_v1.4.0.bin │ └── stm32-secure-patching-bootloader_NUCLEO-L073RZ_v1.4.0.bin.asc ├── NUCLEO-L412KB │ ├── stm32-secure-patching-bootloader-README_NUCLEO-L412KB_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_NUCLEO-L412KB_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_NUCLEO-L412KB_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_NUCLEO-L412KB_v1.4.0.bin │ └── stm32-secure-patching-bootloader_NUCLEO-L412KB_v1.4.0.bin.asc ├── NUCLEO-L452RE │ ├── stm32-secure-patching-bootloader-README_NUCLEO-L452RE_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_NUCLEO-L452RE_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_NUCLEO-L452RE_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_NUCLEO-L452RE_v1.4.0.bin │ └── stm32-secure-patching-bootloader_NUCLEO-L452RE_v1.4.0.bin.asc ├── NUCLEO-L476RG │ ├── stm32-secure-patching-bootloader-README_NUCLEO-L476RG_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_NUCLEO-L476RG_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_NUCLEO-L476RG_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_NUCLEO-L476RG_v1.4.0.bin │ └── stm32-secure-patching-bootloader_NUCLEO-L476RG_v1.4.0.bin.asc ├── NUCLEO-L496ZG │ ├── stm32-secure-patching-bootloader-README_NUCLEO-L496ZG_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_NUCLEO-L496ZG_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_NUCLEO-L496ZG_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_NUCLEO-L496ZG_v1.4.0.bin │ └── stm32-secure-patching-bootloader_NUCLEO-L496ZG_v1.4.0.bin.asc ├── NUCLEO-WL55JC │ ├── stm32-secure-patching-bootloader-README_NUCLEO-WL55JC_v1.4.0.txt │ ├── stm32-secure-patching-bootloader-linker-gcc_NUCLEO-WL55JC_v1.4.0.ld │ ├── stm32-secure-patching-bootloader-postbuild_NUCLEO-WL55JC_v1.4.0.sh │ ├── stm32-secure-patching-bootloader_NUCLEO-WL55JC_v1.4.0.bin │ └── stm32-secure-patching-bootloader_NUCLEO-WL55JC_v1.4.0.bin.asc └── README.md ├── Linker ├── README.md ├── stm32-secure-patching-bootloader-app-linker-sections-multiseg_v1.4.0.ld └── stm32-secure-patching-bootloader-app-linker-sections_v1.4.0.ld ├── README.md ├── Scripts ├── README.md ├── STM32CubeIDE │ └── postbuild.sh ├── make_keys_v6m.bat └── make_keys_v7m.bat ├── Test ├── B-L072Z-LRWAN1 │ ├── BOOT_TestApp_B-L072Z-LRWAN1_v1.4.0.bin │ ├── TestApp_B-L072Z-LRWAN1_v1.4.0_v1.4.1.sfbp │ └── TestApp_B-L072Z-LRWAN1_v1.4.1.sfb ├── B-L4S5I-IOT01A │ ├── BOOT_TestApp_B-L4S5I-IOT01A_v1.4.0.bin │ ├── TestApp_B-L4S5I-IOT01A_v1.4.0_v1.4.1.sfbp │ └── TestApp_B-L4S5I-IOT01A_v1.4.1.sfb ├── DISCO-F469I │ ├── BOOT_TestApp_DISCO-F469I_v1.4.0.hex │ ├── TestApp_DISCO-F469I_v1.4.0_v1.4.1.sfbp │ └── TestApp_DISCO-F469I_v1.4.1.sfb ├── DISCO-F769I │ ├── BOOT_TestApp_DISCO-F769I_v1.4.0.hex │ ├── TestApp_DISCO-F769I_v1.4.0_v1.4.1.sfbp │ └── TestApp_DISCO-F769I_v1.4.1.sfb ├── DISCO-H745I │ ├── BOOT_TestApp_DISCO-H745I_v1.4.0.hex │ ├── TestApp_DISCO-H745I_v1.4.0_v1.4.1.sfbp │ └── TestApp_DISCO-H745I_v1.4.1.sfb ├── DISCO-L476G │ ├── BOOT_TestApp_DISCO-L476G_v1.4.0.bin │ ├── TestApp_DISCO-L476G_v1.4.0_v1.4.1.sfbp │ └── TestApp_DISCO-L476G_v1.4.1.sfb ├── DISCO-L496G │ ├── BOOT_TestApp_DISCO-L496G_v1.4.0.bin │ ├── TestApp_DISCO-L496G_v1.4.0_v1.4.1.sfbp │ └── TestApp_DISCO-L496G_v1.4.1.sfb ├── DISCO-L4R9I │ ├── BOOT_TestApp_DISCO-L4R9I_v1.4.0.hex │ ├── TestApp_DISCO-L4R9I_v1.4.0_v1.4.1.sfbp │ └── TestApp_DISCO-L4R9I_v1.4.1.sfb ├── DISCO-L562E │ ├── BOOT_TestApp_DISCO-L562E_v1.4.0.bin │ ├── TestApp_DISCO-L562E_v1.4.0_v1.4.1.sfbp │ └── TestApp_DISCO-L562E_v1.4.1.sfb ├── L073RZ-NUCLEO │ ├── BOOT_TestApp_L073RZ-NUCLEO_v1.4.0.bin │ ├── TestApp_L073RZ-NUCLEO_v1.4.0_v1.4.1.sfbp │ └── TestApp_L073RZ-NUCLEO_v1.4.1.sfb ├── LORA-E5-DEV │ ├── BOOT_TestApp_LORA-E5-DEV_v1.4.0.bin │ ├── TestApp_LORA-E5-DEV_v1.4.0_v1.4.1.sfbp │ └── TestApp_LORA-E5-DEV_v1.4.1.sfb ├── NUCLEO-F429ZI │ ├── BOOT_TestApp_NUCLEO-F429ZI_v1.4.0.bin │ ├── TestApp_NUCLEO-F429ZI_v1.4.0_v1.4.1.sfbp │ └── TestApp_NUCLEO-F429ZI_v1.4.1.sfb ├── NUCLEO-G0B1RE │ ├── BOOT_TestApp_NUCLEO-G0B1RE_v1.4.0.bin │ ├── TestApp_NUCLEO-G0B1RE_v1.4.0_v1.4.1.sfbp │ └── TestApp_NUCLEO-G0B1RE_v1.4.1.sfb ├── NUCLEO-L412KB │ ├── BOOT_TestApp_NUCLEO-L412KB_v1.4.0.bin │ ├── TestApp_NUCLEO-L412KB_v1.4.0_v1.4.1.sfbp │ └── TestApp_NUCLEO-L412KB_v1.4.1.sfb ├── NUCLEO-L452RE │ ├── BOOT_TestApp_NUCLEO-L452RE_v1.4.0.bin │ ├── TestApp_NUCLEO-L452RE_v1.4.0_v1.4.1.sfbp │ └── TestApp_NUCLEO-L452RE_v1.4.1.sfb ├── NUCLEO-L476RG │ ├── BOOT_TestApp_NUCLEO-L476RG_v1.4.0.bin │ ├── TestApp_NUCLEO-L476RG_v1.4.0_v1.4.1.sfbp │ └── TestApp_NUCLEO-L476RG_v1.4.1.sfb ├── NUCLEO-L496ZG │ ├── BOOT_TestApp_NUCLEO-L496ZG_v1.4.0.bin │ ├── TestApp_NUCLEO-L496ZG_v1.4.0_v1.4.1.sfbp │ └── TestApp_NUCLEO-L496ZG_v1.4.1.sfb ├── NUCLEO-WL55JC │ ├── BOOT_TestApp_NUCLEO-WL55JC_v1.4.0.bin │ ├── TestApp_NUCLEO-WL55JC_v1.4.0_v1.4.1.sfbp │ └── TestApp_NUCLEO-WL55JC_v1.4.1.sfb └── README.md └── Tools ├── README.md ├── jdiff.exe ├── keys.py ├── prepareimage.py ├── requirements.txt └── translate_key_opcode.py /.gitignore: -------------------------------------------------------------------------------- 1 | # stm32-secure-patching-bootloader 2 | 3 | ## Prepareimage Python cache directory and compiled files 4 | __pycache__ 5 | 6 | -------------------------------------------------------------------------------- /Docs/README.md: -------------------------------------------------------------------------------- 1 | ## STM32 Secure Patching Bootloader 2 | 3 | ## Documentation Overview 4 | 5 | * [Graphic](stm32-secure-patching-bootloader-MultiSegment_rev1_Dec2021.pdf) describing MultiSegment feature in more detail. 6 | * [Quick Start Guide](stm32-secure-patching-bootloader-QSG_rev4_Mar2023.pdf) in PDF form with screenshots. 7 | 8 | ## Quick Start Guide 9 | 10 | Integrating the stm32-secure-patching-bootloader is a simple five step process: 11 | 1. Adding bootloader files to your project repository. 12 | 2. Configuring STM32CubeIDE. 13 | 3. Adjusting your project's linker script .ld file. 14 | 4. Adjusting your project's system_stm32xxxx.c file. 15 | 5. Generating your project's encryption and signing keys. 16 | 17 | Please refer to [stm32-secure-patching-bootloader-demoapp](https://github.com/firmwaremodules/stm32-secure-patching-bootloader-demoapp) repository for working projects already implementing these steps or to the STM32 Cube repositories we maintain that has the bootloader integrated with select reference projects at [here](https://github.com/orgs/firmwaremodules/repositories). 18 | 19 | Also refer to this [Quick Start Guide](stm32-secure-patching-bootloader-QSG_rev4_Mar2023.pdf) PDF document for more details including images and screenshots. 20 | 21 | 1. Adding bootloader files to your project repository 22 | 23 | * Create a directory called `Bootloader` in your project root. 24 | * Copy the directories `Include`, `Linker`, `Scripts`, `Tools` into it. 25 | * Copy the `Libs` directory, but only the board subdirectories that you are needing. E.g. copy DISCO-F769I directory into your Libs directory if you are using that board. 26 | * As an alternative, you can add the bootloader files as a git submodule with `git submodule add https://github.com/firmwaremodules/stm32-secure-patching-bootloader Bootloader`. 27 | 28 | 2. Configure STM32CubeIDE. 29 | 30 | We need to add the postbuild command line and update the include and linker paths. 31 | 32 | * Update Post-build steps C/C++ Build -> Settings -> Build Steps 33 | 34 | ``` 35 | "../../../../../../../Bootloader/Scripts/STM32CubeIDE/postbuild.sh" "${BuildArtifactFileBaseName}" "../../Keys" "../../../../../Binary" "../../../../../../../Bootloader/Libs" "0.0.0" "v1.0.0" "DISCO-L4R9I" "v1.3.0" 36 | | | | | | | | | | 37 | \- Name of postbuild script, relative to build dir | | | | | | | | 38 | | | | | | | | | 39 | \- Name of applcation build artifact (Build Artifact -> Artifact Name) | | | | 40 | | | | | | | | 41 | \- Directory where Keys are, relative to build dir, according to DemoApp reference design. | | 42 | | | | | | | 43 | \- Directory where Outputs are placed and patch reference binaries are found, relative to build dir, according to DemoApp reference design. 44 | | | | | | 45 | \- Directory where bootloader libraries are, relative to build dir. | 46 | | | | | 47 | \- 'To' version (version to build) (auto-mode in this example) 48 | | | | 49 | \- 'From' version (reference for patch generation) (from v1.0.0 in this example) 50 | | | 51 | \- bootloader library to link with (in Libs dir) 52 | | 53 | \- Version of bootloader library to link with (in Libs dir) 54 | 55 | ``` 56 | 57 | * Add path to bootloader include: C/C++ Build -> Settings -> MCU GCC Compiler -> Include paths : `../../../../../../../Bootloader/Include` 58 | 59 | * Add paths to bootloader linker files: C/C++ Build -> Settings -> MCU GCC Linker -> Miscellaneous : `-Xlinker -L ../../../../../../../Bootloader/Libs/NUCLEO-L073RZ -L ../../../../../../../Bootloader/Linker` 60 | 61 | 3. Adjust your application's linker script. 62 | 63 | At minimum we need to tell the linker where your application's new start offset is in flash. This is defined by the bootloader's linker configuration file `stm32-secure-patching-bootloader-linker-gcc__.ld`. 64 | It defines some symbols that we may need, minimally it is `STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START`. Then your application's interrupt vector table has to be offset from this by the minimum size of your vector table (to account for the image header), also defined as `VECTOR_SIZE` in the linker configuration file. 65 | 66 | ``` 67 | /* For this example end of RAM on STM32L073 is 0x20005000 = 20 KB*/ 68 | 69 | INCLUDE stm32-secure-patching-bootloader-linker-gcc_NUCLEO-L073RZ_v1.3.0.ld 70 | 71 | APPLI_region_intvec_start__ = STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START + VECTOR_SIZE; 72 | APPLI_region_ROM_start = STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START + VECTOR_SIZE + VECTOR_SIZE; 73 | APPLI_region_ROM_length = STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END - APPLI_region_ROM_start + 1; 74 | APPLI_region_RAM_start = STM32_SECURE_PATCHING_BOOTLOADER_RAM_START; 75 | APPLI_region_RAM_length = 0x20005000 - APPLI_region_RAM_start; 76 | 77 | MEMORY 78 | { 79 | ISR_VECTOR (rx) : ORIGIN = APPLI_region_intvec_start__, LENGTH = VECTOR_SIZE 80 | APPLI_region_ROM : ORIGIN = APPLI_region_ROM_start, LENGTH = APPLI_region_ROM_length 81 | APPLI_region_RAM : ORIGIN = APPLI_region_RAM_start, LENGTH = APPLI_region_RAM_length 82 | } 83 | ``` 84 | Put the .isr_vector section in `ISR_VECTOR`, all flash sections in `APPLI_region_ROM` and all RAM sections in `APPLI_region_RAM`. 85 | 86 | To your SECTIONS, add the following: 87 | 88 | ``` 89 | ... 90 | 91 | /* Extra ROM section (last one) to make sure the binary size is a multiple of the AES block size (16 bytes) */ 92 | .align16 : 93 | { 94 | . = . + 1; /* _edata=. is aligned on 8 bytes so could be aligned on 16 bytes: add 1 byte gap */ 95 | . = ALIGN(16) - 1; /* increment the location counter until next 16 bytes aligned address (-1 byte) */ 96 | BYTE(0); /* allocate 1 byte (value is 0) to be a multiple of 16 bytes */ 97 | } > APPLI_region_ROM 98 | 99 | ... 100 | 101 | ``` 102 | 103 | A multi-target generic linker script that works with most STM32 targets is provided in the bootloader `Linker` directory. See this [reference project linker script](https://github.com/firmwaremodules/stm32-secure-patching-bootloader-demoapp/tree/main/App/Project/DemoApp/NUCLEO-L073RZ/STM32CubeIDE/DemoApp_NUCLEO-L073RZ/STM32L073RZTx.ld). 104 | 105 | For a TouchGFx multi-segment application (assets on external QSPI or OSPI flash), use this template: 106 | 107 | ``` 108 | /* For this example end of RAM on STM32L4R9I is 0x200A0000 = 640 KB*/ 109 | INCLUDE stm32-secure-patching-bootloader-linker-gcc_DISCO-L4R9I_v1.3.0.ld 110 | 111 | APPLI_region_intvec_start__ = STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START + VECTOR_SIZE; 112 | APPLI_region_ROM_start = STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START + VECTOR_SIZE + VECTOR_SIZE; 113 | APPLI_region_ROM_length = STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END - APPLI_region_ROM_start + 1; 114 | APPLI_region_RAM_start = STM32_SECURE_PATCHING_BOOTLOADER_RAM_START; 115 | APPLI_region_RAM_length = 0x200A0000 - APPLI_region_RAM_start; 116 | 117 | MEMORY 118 | { 119 | ISR_VECTOR (rx) : ORIGIN = APPLI_region_intvec_start__, LENGTH = VECTOR_SIZE 120 | APPLI_region_ROM : ORIGIN = APPLI_region_ROM_start, LENGTH = APPLI_region_ROM_length 121 | APPLI_region_RAM : ORIGIN = APPLI_region_RAM_start, LENGTH = APPLI_region_RAM_length 122 | QSPI (rx) : ORIGIN = STM32_SECURE_PATCHING_BOOTLOADER_MULTISEG_START, LENGTH = 64M 123 | } 124 | 125 | ``` 126 | 127 | To your SECTIONS, add the following: 128 | 129 | ``` 130 | /* Extra ROM section (last one) to make sure the binary size is a multiple of the AES block size (16 bytes) */ 131 | .align16 : 132 | { 133 | . = . + 1; /* _edata=. is aligned on 8 bytes so could be aligned on 16 bytes: add 1 byte gap */ 134 | . = ALIGN(16) - 1; /* increment the location counter until next 16 bytes aligned address (-1 byte) */ 135 | BYTE(0); /* allocate 1 byte (value is 0) to be a multiple of 16 bytes */ 136 | } > APPLI_region_ROM 137 | 138 | /* Section for placement of resources into QSPI segment 139 | * This is not contiguous with the "ROM" segment, but must also be aligned 140 | * to 16 bytes for AES requirement. 141 | */ 142 | ExtFlashSection : 143 | { 144 | *(ExtFlashSection) 145 | . = . + 1; /* _edata=. is aligned on 8 bytes so could be aligned on 16 bytes: add 1 byte gap */ 146 | . = ALIGN(16) - 1; /* increment the location counter until next 16 bytes aligned address (-1 byte) */ 147 | BYTE(0); /* allocate 1 byte (value is 0) to be a multiple of 16 bytes */ 148 | } >QSPI 149 | ``` 150 | 151 | 152 | 4. Adjust your system_stm32xxxx.c file. 153 | 154 | This file programs the VTOR register (Vector Table Offset Register) by your application in the early startup phase so that interrupts invoke your application's handlers at the linked offset instead of the bootloader's. 155 | 156 | ``` 157 | extern uint32_t APPLI_region_intvec_start__; 158 | #define INTVECT_START ((uint32_t)& APPLI_region_intvec_start__) 159 | 160 | void SystemInit(void) 161 | { 162 | ... 163 | 164 | /* Configure the Vector Table location add offset address ------------------*/ 165 | SCB->VTOR = INTVECT_START; 166 | } 167 | 168 | ``` 169 | 170 | 5. Generating your project's encryption and signing keys and machine.txt file. 171 | 172 | Use the make_keys_v7m.bat script (for L0, F0, G0 targets use make_keys_v6m.bat) under Scripts to call a Python tool to generate the AES encryption key (firmware confidentiality) and the ECDSA public verification and private signing keys (firmware authenticity). Example on Windows systems to place keys in a Keys directory: 173 | 174 | ``` 175 | c:\stm32-secure-patching-bootloader-demoapp\Bootloader\Scripts>make_keys_v7m.bat ..\..\App\Project\DemoApp\DISCO-F769I\STM32CubeIDE\Keys 176 | 177 | make_keys_v7m.bat : Generate new secure keys for stm32-secure-patching-bootloader 178 | Making ..\..\App\Project\DemoApp\DISCO-F769I\STM32CubeIDE\Keys/Cipher_Key_AES_CBC.bin 179 | Making ..\..\App\Project\DemoApp\DISCO-F769I\STM32CubeIDE\Keys/Signing_PrivKey_ECC.txt 180 | Making ..\..\App\Project\DemoApp\DISCO-F769I\STM32CubeIDE\Keys/machine.txt 181 | ``` 182 | 183 | Run `make_keys_v7m ` 184 | 185 | If you're not using Windows, then all you need to do is look inside make_keys_v7m.bat and run the Python scripts directly. The Keys directory is referenced by the postbuild.sh post-build command line in the IDE. This directory can be anywhere and called anything by adjusting the post-build command line. 186 | 187 | Ensure there is a file called `machine.txt` in the `Keys` dir. Add one line to it: `V7M` for all targets unless you're using a cortex-M0, then add `V6M` instead. `make_keys_vXm.bat` will have already created this file. 188 | 189 | **Important Note** 190 | 191 | These keys are also used by the bootloader to differentiate between compatible firmware loads! That is, the stm32-secure-patching-bootloader will attempt to update to any firmware that is presented that can be successfully decrypted and signature verified. There is no 'product ID' field in the header. The keys are the product ID. Of course, the point of having this type of security is to prevent loading of firmware except for those loads you explicitly authorize by way of signing during the build (automatically done by postbuild.bat). But if you are running multiple products or even incompatible hardware revisions within the same product line, you must ensure to have unique keys setup for each STM32CubeIDE build project (the path to the keys is specified in the postbuild.sh post-build command line and in these examples is called Keys). 192 | 193 | 194 | **That's it.** There is a bit to do here, but all things considered it is pretty minimal and your application sources and build procedure is virtually untouched by the addition of the stm32-secure-patching-bootloader. 195 | 196 | 197 | ### Build Products 198 | 199 | The stm32-secure-patching-bootloader postbuild process produces three or four artifacts and places them in the specified output directory (`Binary` in the above). 200 | 201 | Naming convention: 202 | 203 | *Combined binary:* 204 | 205 | * ` BOOT___.[hex | bin]` 206 | 207 | *Update binary:* 208 | 209 | * `__.[sfb | sfbp]` 210 | 211 | Combined binaries are for loading onto the target by a programming tool such as STM32CubeProgrammer during production. 212 | 213 | Update binaries are for distribution to customers or to your apps and cloud services for in-field updates. 214 | 215 | 1. Combined binaries: `BOOT_DemoApp_NUCLEO-L073RZ_v1.0.0.hex`, `BOOT_DemoApp_NUCLEO-L073RZ_v1.0.0.bin` (.bin produced only when multisegment is not enabled) 216 | 2. Secured in-field firmware full update file: `DemoApp_NUCLEO-L073RZ_v1.0.0.sfb` (full image) 217 | 3. Secured in-field firmware patch update file: `DemoApp_NUCLEO-L073RZ_v1.0.0_v1.1.0.sfbp` (patch - produced only if reference version v1.0.0 exists in `Binary\PatchRef`) 218 | 219 | Note: the `` appended to the file names is a direct copy of either the post-build command-line's 'to' version, or else of the output of `git describe --tags --always --dirty` if the 'to' version is in auto mode '0.0.0' or '0'. When using the auto mode (recommended), use git tagging to set the version. A semantic version tag may be prepended with a 'v' or not. Firmware Modules projects like to prepend versions with a 'v', so a tag might be 'v1.3.1'. Either way works. 220 | 221 | Also note: the firmware image header contains a 4-byte field for version and therefore cannot directly accommodate a non-semantic version such as v1.3.1-7-gc32667a that may arise during development load testing. The version generator embedded into the postbuild.sh script can safely handle this scenario by adding the *number of commits since* value to the build number, so v1.3.1-7 becomes 1.3.8 in the header. 222 | 223 | ### Notes 224 | 225 | #### General Notes 226 | 227 | * Patch files .sfbp only work if the source version already exists on the target device. E.g. to update from v1.1.7 to v1.2.0, version v1.1.7 must exist on the device as the active image in SLOT0. 228 | 229 | * To update from v1.0.0 to v1.4.0 when only patches of v1.0.0_v1.1.0, v1.1.0_v1.2.0, v1.2.0_v1.3.0, v1.3.0_v1.4.0 are available, each patch must be applied in series. For each one, firmware is installed by the bootloader through a reboot cycle. 230 | 231 | * The build system (STM32CubeIDE) postbuild command line must explicitly set what the reference firmware version is to build a patch from. With this flexibility it is possible to build patches from any version. Commonly this 'from version' is updated from one release to the next to build a series of patchable updates (v1.0.0->v1.1.0, v1.1.0->v1.2.0 etc). Of course you could create a patch from v1.0.0->v1.2.0 and post this to your update server; if your 'patch picker' algorithm was smart enough it could select the best patch from a list of available patches. 232 | 233 | * Full image files .sfb can be used to update to any version and do not depend on what is currently on the device. These could serve as a fall-back in case the hypothetical 'patch picker' implemented in the user application cannot find a suitable patch for download. 234 | 235 | * The 'patch picker' is implemented in the USB flash drive updater to select the first patch in the root directory that matches the current version on the device and contains the highest 'to' version. It is able to perform a 'patch chain' update as described above by repeatedly rebooting and updating to the next higher patch version. 236 | 237 | #### Security Notes 238 | 239 | * The stm32-secure-patching-bootloader strikes a balance between ease of integration, broad platform support and selection of security features that are enabled. 240 | 241 | * The bootloader system is designed so that your products and firmware update files can be distributed into uncontrolled environments. This means firmware confidentiality is ensured through AES encryption, and firmware and device integrity are ensured through ECDSA (digital signatures). The AES encryption and the ECDSA public verification keys are stored in your device's internal flash. The AES encryption and ECDSA private signing key are typically stored in your firmware development repository (e.g. on GitHub, your developer's and build PCs). 242 | 243 | * Those that would attempt to undermine your products and solutions know that these keys exist. Thus, protection of these keys is paramount. You must create a root of trust on each of the devices you deploy by way of enabling RDP Level 2 through the stm32-secure-patching-bootloader production build (you can get this build upon request when you register the bootloader at firmwaremodules.com). This build will automatically check and enable RDP Level 2 on each boot to help mitigate potential RDP regression attack vectors (yes these do exist). Note that when RDP Level 2 is enabled, you permanently forfeit the ability to connect a debugger to your devices (a good thing when security is concerned, but not good if you're still in development). 244 | 245 | * The bootloader system is not designed to protect your device and secrets from your own firmware application. If you don't trust your application or the way it works (e.g. you think it might offer a way for an attacker to read out contents of memory) then this bootloader system is not for you, or at least you must be aware that internal protections such as proprietary readout protection (PCROP) or firewalls are not implemented. These are by no means foolproof even when enabled. Don't offer a command-line interface that has memory peek and poke commands. 246 | 247 | * Finally, you should assume that if an attacker has physical access to your device and is determined enough (time and resources) then your secrets will eventually be extracted no matter what you do. You need to weigh the expense and effort someone (or some group) would go to obtain your firmware update AES encryption key and public signature verification key, and the 'payoff' that may be associated with that effort. 248 | -------------------------------------------------------------------------------- /Docs/stm32-secure-patching-bootloader-MultiSegment_rev1_Dec2021.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Docs/stm32-secure-patching-bootloader-MultiSegment_rev1_Dec2021.pdf -------------------------------------------------------------------------------- /Docs/stm32-secure-patching-bootloader-QSG_rev4_Mar2023.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Docs/stm32-secure-patching-bootloader-QSG_rev4_Mar2023.pdf -------------------------------------------------------------------------------- /Include/README.md: -------------------------------------------------------------------------------- 1 | ## STM32 Secure Patching Bootloader 2 | 3 | ## Includes 4 | 5 | The application-level 'C' interface to the bootloader is provided here. With this interface the application can invoke functions to perform operations such as in-application OTA firmware update or read bootloader and application firmware versions. 6 | 7 | 8 | -------------------------------------------------------------------------------- /Include/stm32_secure_patching_bootloader_interface_v1.4.0.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32_secure_patching_bootloader_interface.h 4 | * @brief Application interface to stm32-secure-patching-bootloader. 5 | ****************************************************************************** 6 | */ 7 | /* 8 | * Copyright (c) 2021-2023 Firmware Modules Inc. 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy 11 | * of this software and associated documentation files(the "Software"), to deal 12 | * in the Software without restriction, including without limitation the rights 13 | * to use, copy, modify, merge, publish, distribute, sublicense, and /or sell 14 | * copies of the Software, and to permit persons to whom the Software is 15 | * furnished to do so, subject to the following conditions : 16 | * 17 | * The above copyright notice and this permission notice shall be included in all 18 | * copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 24 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 25 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 26 | * OR OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | /** 30 | * @brief Secure Engine Error definition 31 | */ 32 | typedef enum 33 | { 34 | SE_ERROR = 0U, 35 | SE_SUCCESS = !SE_ERROR 36 | } SE_ErrorStatus; 37 | 38 | 39 | /** 40 | * @brief Secure Engine Status definition 41 | */ 42 | typedef enum 43 | { 44 | SE_OK = 0U, /*!< Secure Engine OK */ 45 | SE_KO, /*!< Secure Engine KO */ 46 | SE_INIT_ERR, /*!< Secure Engine initialization error */ 47 | SE_BOOT_INFO_ERR, /*!< An error occurred when accessing BootInfo area */ 48 | SE_BOOT_INFO_ERR_FACTORY_RESET, /*!< A factory reset has been executed to recover the BootInfo Initialization failure */ 49 | SE_SIGNATURE_ERR, /*!< An error occurred when checking FW signature (Tag) */ 50 | SE_ERR_FLASH_READ /*!< An error occurred trying to read the Flash */ 51 | } SE_StatusTypeDef; 52 | 53 | /*! 54 | * Provides services to access bootloader and application versions, perform 55 | * in-application firmware updates and access the user-provisioned OTP secure data area. 56 | * 57 | * The patching engine is the core of the stm32-secure-patching-bootloader firmware 58 | * update system. It supports over-the-air streaming in-application firmware updating 59 | * that is highly tolerant to link or device failure - 60 | * the target device's running application remains safe at all times during this 61 | * process thanks to the dual slot architecture. 62 | * 63 | * Patching engine APIs (SE_PATCH_) are designed to process Secure Firmware Binary (.sfb) 64 | * or Secure Firmware Binary Patch (.sfbp) files generated by the 65 | * stm32-secure-patching-bootloader build system. The user is required to pass the 66 | * file binary data in arbitrarily sized chunks through the Data() API. 67 | * 68 | * Full-image .sfb files contain the entire new firmware update image and therefore 69 | * updates can be performed to any available newer version. 70 | * Patch files .sfbp, on the other hand, only contain the differences between the 71 | * current version on the device and the new version. Consequently, patch files 72 | * only work if the required "from" version already exists on the device with a 73 | * fully matching SHA256 digest. Attempting an update with an incorrect patch file 74 | * has no effect on the system or running application - the patch file is immediately rejected 75 | * due to "from" version or SHA256 mismatch (fields digitally signed in the file header). 76 | * The choice of using full or patch file update images depends 77 | * on delivery method bandwidth constraints and how much attention is paid 78 | * to the firmware release and delivery process in your organization. 79 | * 80 | * The patching engine will NOT update firmware to older versions (security feature). 81 | * If an older version (i.e. a 'downgrade') is required, the changes must be 82 | * reverted/implemented then built with a new version number. 83 | * 84 | * The patching engine utilizes the buffers provided by the caller of the Data() API. 85 | * There are no requirements on these buffers - they can contain as little as 1 byte 86 | * of .sfb or .sfbp file data per invocation. 87 | * 88 | * The system employs multiple protections to ensure it is virtually impossible to 89 | * inject wrong or malformed firmware update binary data and cause fault or failure in the 90 | * system. Digital signatures with SHA256 integrity checking ensure correctness of binary data. 91 | * 92 | * @a(Security Policies) 93 | * Firmware images are protected from tampering (digitally signed) and from IP theft 94 | * (encrypted). The methods selected to transport the firmware update images (.sfb, .sfbp) 95 | * are not required to be secured and can be user-distributed (e.g. from a public web page). 96 | * Chip-level readout protection (RDP level 2) option byte is recommended to be 97 | * programmed for production devices to protect the digital signature public key (ECDSA) and 98 | * the decryption private key (AES). 99 | * Production versions of the stm32-secure-patching-bootloader enforce chip-level readout 100 | * protection (RDP level 2) at each startup to help protect against possible physical attack vectors. 101 | * 102 | * @a(Thread Safety) 103 | * The APIs in this module are NOT thread-safe 104 | * and must all be called from the same context, or unpredictable results 105 | * may occur. 106 | * 107 | * @a(Other Notes) 108 | * The reboot delay "window" is not supported at this time. Specifying a delay 109 | * other than RebootDelay_IMMEDIATE or RebootDelay_COMMAND to {@link #start} will 110 | * be rejected. 111 | * 112 | */ 113 | 114 | #include 115 | #include 116 | 117 | /*! 118 | * @value(StatusCode_NONE) No status code 119 | * @value(StatusCode_COMPLETED) Response to a completed API call or the update has completed in case of status poll 120 | * @value(StatusCode_INVALID_ARG) Response to an invalid API argument 121 | * @value(StatusCode_INVALID_IMAGE) Reponse to early header verification failure 122 | * @value(StatusCode_IMAGE_TOO_LARGE) Fail if provided length is too large, or embedded image length is too large 123 | * @value(StatusCode_IMAGE_TOO_SMALL) Fail if embedded image length is smaller than the minimum data length 124 | * @value(StatusCode_SECTION_NOT_AVAILABLE) Non-volatile section corresponding to the supplied ImageType cannot be found 125 | * @value(StatusCode_SECTION_ERASE_FAILURE) Error preparing (erasing) update target section 126 | * @value(StatusCode_SECTION_WRITE_FAILURE) Error writing data to update target section 127 | * @value(StatusCode_IMAGE_VERSION_FAILURE) Image version embedded in header is less than version of currently running image and update rejected 128 | * @value(StatusCode_INVALID_SECTION_KEY) The supplied firmware update image has a different section key than what is associated with the application currently running on the device 129 | * @value(StatusCode_IMAGE_VERIFY_FAILURE) Response after the completely written firmware image verification has failed 130 | * @value(StatusCode_INVALID_STATE) Response to an API called in an invalid state, e.g. supplying more data when waiting for reboot 131 | * @value(StatusCode_INVALID_ORDER) Supplied data with incorrect order for the current state 132 | * @value(StatusCode_TOO_FEW_BYTES) Supplied first data packet with less than minimum required bytes 133 | * @value(StatusCode_PARSER_ERROR) Update container format parser has encountered an unrecoverable error in the byte stream 134 | * @value(StatusCode_DECRYPTION_ERROR) Update container format stream decryption has failed 135 | * @value(StatusCode_INSTALL_ERROR) Error finalizing the newly written firmware in download slot (automatically or through SE_PATCH_InstallAtNextReset) 136 | * @value(StatusCode_FLASH_ERROR) Flash (possibly external) initialization error 137 | * @value(StatusCode_FLASH_SEGMENT_ERROR) Error initializing the SEGMENT read layer for external flash MultiSegment feature 138 | * @value(StatusCode_FLASH_CIPHER_ERROR) Error initializing the CIPHER write layer for external flash MultiSegment feature 139 | */ 140 | typedef enum 141 | { 142 | SE_PATCH_StatusCode_NONE, 143 | SE_PATCH_StatusCode_COMPLETED, 144 | SE_PATCH_StatusCode_INVALID_ARG, 145 | SE_PATCH_StatusCode_INVALID_PATCH_IMAGE, 146 | SE_PATCH_StatusCode_INVALID_SOURCE_IMAGE, 147 | SE_PATCH_StatusCode_INVALID_TARGET_IMAGE, 148 | SE_PATCH_StatusCode_INVALID_PATCH_TAG, 149 | SE_PATCH_StatusCode_IMAGE_TOO_LARGE, 150 | SE_PATCH_StatusCode_IMAGE_TOO_SMALL, 151 | SE_PATCH_StatusCode_SECTION_NOT_AVAILABLE, 152 | SE_PATCH_StatusCode_SECTION_ERASE_FAILURE, 153 | SE_PATCH_StatusCode_SECTION_WRITE_FAILURE, 154 | SE_PATCH_StatusCode_IMAGE_VERSION_FAILURE, 155 | SE_PATCH_StatusCode_INVALID_SECTION_KEY, 156 | SE_PATCH_StatusCode_IMAGE_VERIFY_TAG_FAILURE, 157 | SE_PATCH_StatusCode_IMAGE_VERIFY_ALG_FAILURE, 158 | SE_PATCH_StatusCode_IMAGE_DECRYPT_FAILURE, 159 | SE_PATCH_StatusCode_INVALID_STATE, 160 | SE_PATCH_StatusCode_INVALID_ORDER, 161 | SE_PATCH_StatusCode_TOO_FEW_BYTES, 162 | SE_PATCH_StatusCode_PARSER_ERROR, 163 | SE_PATCH_StatusCode_DECRYPTION_ERROR, 164 | SE_PATCH_StatusCode_INSTALL_ERROR, 165 | SE_PATCH_StatusCode_FLASH_ERROR, 166 | SE_PATCH_StatusCode_FLASH_SEGMENT_ERROR, 167 | SE_PATCH_StatusCode_FLASH_CIPHER_ERROR, 168 | SE_PATCH_StatusCode__MAX__ 169 | } SE_PATCH_StatusCode; 170 | 171 | 172 | /*! 173 | * High-level patching engine image types. 174 | * 175 | * These are the types of firmware images that may be presented to the patching engine. 176 | */ 177 | typedef enum 178 | { 179 | SE_PATCH_ImageType_NONE = 0, 180 | SE_PATCH_ImageType_APP 181 | } SE_PATCH_ImageType; 182 | 183 | 184 | 185 | /*! Set the delay type to COMMAND to specify rebooting upon command. 186 | * The application is responsible for marking the update as "ready to install". 187 | */ 188 | #define SE_PATCH_RebootDelay_COMMAND ((uint32_t)0xFFFF) 189 | 190 | /*! Set the delay type to IMMEDIATE to specify rebooting and installing immediately. 191 | */ 192 | #define SE_PATCH_RebootDelay_IMMEDIATE ((uint32_t)0) 193 | 194 | /*! Set the delay type to NEXT to specify installation on next reboot. 195 | * The user application is still responsible for initiating the reboot. 196 | */ 197 | #define SE_PATCH_RebootDelay_NEXT ((uint32_t)1) 198 | 199 | /*! 200 | * Update start setup data structure. 201 | * 202 | * @field(type) Target update location of firmware image presented to patching engine. 203 | * This field may be set if known, or may be omitted (set to NONE) to use the firmware update image's 204 | * embedded type determined on-the-fly. 205 | * @field(rebootDelay) Specify the reboot delay that is to occur after a completed firmware update. 206 | * @p(blist) 207 | * - RebootDelay_IMMEDIATE reboot immediately upon successful written image verification. 208 | * - 1 to 0xFFFE random delay, in seconds, selected from within this window before rebooting as if RebootDelay_IMMEDIATE was selected. 209 | * - RebootDelay_COMMAND wait indefinately upon successful written image verification. 210 | * The user is responsible for rebooting the system, e.g. by calling {@link fm.driver.System#reset}. 211 | * @p 212 | * @field(totalLength) Provide if the image length is known - only used to initially reject an update if it is too large 213 | * for the device before examining the actual header. Set to 0 to ignore this first check and use the 214 | * embedded image header length in a subsequent {@link #data} call. The type must also be specified 215 | * (not ImageType_NONE) to be able to validate this length parameter. 216 | */ 217 | typedef struct 218 | { 219 | SE_PATCH_ImageType type; 220 | uint16_t rebootDelay; 221 | uint32_t totalLength; 222 | } SE_PATCH_StartInfo; 223 | 224 | /*! 225 | * Status reporting enumeration indicating the current stage of 226 | * the update process. 227 | * 228 | * @value(Stage_IDLE) Updater is idle and awaiting a start command. 229 | * @value(Stage_UPDATE) Updater is actively processing data commands. 230 | * @value(Stage_VERIFIED) Updater has finished update and written a valid image 231 | * to non-volatile storage that is ready to be run on the 232 | * next reboot. 233 | */ 234 | typedef enum 235 | { 236 | SE_PATCH_Stage_IDLE, 237 | SE_PATCH_Stage_UPDATE, 238 | SE_PATCH_Stage_VERIFIED 239 | } SE_PATCH_Stage; 240 | 241 | /*! 242 | * Command response structure. 243 | * 244 | * There are different semantics to the completed flag depending on how it 245 | * is obtained (as API result or through {@link #poll}). 246 | * 247 | * If this status is polled for at any time after an update has successfully completed 248 | * but the system has not yet restarted, the `completed` flag is set, the `accumBytes` records 249 | * the total bytes recorded in the image, and the `stage` will be VERIFIED. 250 | * 251 | * If this status is obtained as an output from an API call, the `completed` flag is set to 252 | * indicate the API call completed. 253 | * 254 | * The accumBytes and totalBytes fields are useful as a progress indicator where 255 | * percentage could be calculated as (accumBytes * 100) / totalBytes. 256 | * 257 | * @field(completed) Set to indicate completion of the specified operation. 258 | * @field(error) Set if an error has occured. An error will result in the stage set to IDLE. 259 | * @field(code) Current status code. 260 | * @field(stage) Set to the updater's current stage at time of generation of this message. 261 | * @field(accumBytes) Records the number of patch bytes received (excluding metadata). 262 | * @field(totalBytes) Records the total number of patch bytes expected (excluding metadata). 263 | */ 264 | typedef struct 265 | { 266 | bool completed; 267 | bool error; 268 | SE_PATCH_StatusCode code; 269 | SE_PATCH_Stage stage; 270 | uint32_t accumBytes; 271 | uint32_t totalBytes; 272 | } SE_PATCH_Status; 273 | 274 | 275 | /*! 276 | * Initialize a Status structure before using it. 277 | */ 278 | void SE_PATCH_InitStatus(SE_PATCH_Status* status); 279 | 280 | /*! 281 | * Helper to print the status. 282 | */ 283 | void SE_PATCH_PrintStatus(SE_PATCH_Status* status); 284 | 285 | /*! 286 | * Starts a firmware update. 287 | * 288 | * This call must be followed up by a {@link #data} or {@link #abort} call provided it 289 | * returns TRUE. 290 | * 291 | * @param(info) Firmware update start parameters. 292 | * @param(status) Supplied structure to be filled in with detailed API result status. 293 | * 294 | * @Note If info.rebootDelay is SE_PATCH_RebootDelay_COMMAND, then user must call SE_PATCH_InstallAtNextReset() 295 | * to mark image for installation at next reset. Otherwise, patch engine will do this. 296 | * 297 | * @return TRUE if the update start request was accepted and the update process 298 | * is awaiting data. 299 | * FALSE if the update start request was rejected for one of these 300 | * failures: 301 | * @p(blist) 302 | * - ImageType was set to a type other than NONE and 303 | * total length is too large for the section allocated to the requested application type. 304 | * - Invalid image type, including `ImageType_BOOT` which is not supported for update. 305 | * - Invalid state. Start can only be initiated when the update stage is IDLE. 306 | * An {@link #abort} is required before restarting an update in-progress. 307 | */ 308 | SE_ErrorStatus SE_PATCH_Init(SE_PATCH_Status* p_PatchStatus, const SE_PATCH_StartInfo* p_StartInfo); 309 | 310 | /*! 311 | * Supply a portion of a stream of data to the firmware patching engine. 312 | * Accepts byte streams from .sfb or .sfbp files. 313 | * 314 | * This function blocks until the operation is completed which may consist of one or both of: 315 | * @p(blist) 316 | * - Writing the data to flash. 317 | * - Erasing flash sectors. 318 | * @p 319 | * 320 | * No action is taken against the non-volatile storage unless the provided 321 | * data was verified to contain the start of a valid firmware image whose 322 | * signature verifies correctly by the public signing key embedded in the 323 | * on-board stm32-secure-patching-bootloader. In the case of a patch file (.sfbp) 324 | * the 'source' firmware's - that is, the firmware already on the device - sha256 tag must also match. 325 | * 326 | * There is no requirement on how many bytes can be delivered in each Data invocation: 327 | * as little as 1 byte can be supplied and there is no upper limit other than the 328 | * size of the buffer the application can supply. 329 | * 330 | * Additionally, the count of bytes is accumulated until the expected number 331 | * of bytes is received, at which time the written firmware image will be fully verified. 332 | * Any subsequent bytes will be ignored. 333 | * 334 | * This API uses the STM32 hardware CRC peripheral. The CRC unit is powered up and configured each 335 | * invocation. It is the caller's responsibility to (re)configure the hardware CRC for their own purposes 336 | * after each SE_PATCH_Data() call completes. 337 | * 338 | * @param(status) Supplied structure to be filled in with detailed API result status. 339 | * @param(data) Pointer to firmware image data buffer 340 | * @param(len) Length of firmware update image data in buffer 341 | * 342 | * @return TRUE - data was accepted. 343 | * FALSE - error accepting data, see status. 344 | * On the first data submission, the update image can be rejected 345 | * with the following errors: 346 | * @p(blist) 347 | * - StatusCode_IMAGE_VERSION_FAILURE 348 | * - StatusCode_INVALID_IMAGE 349 | * - StatusCode_INVALID_SECTION_KEY 350 | * - StatusCode_IMAGE_TOO_LARGE 351 | * - More... 352 | * 353 | */ 354 | SE_ErrorStatus SE_PATCH_Data(SE_PATCH_Status* status, const uint8_t* data, uint32_t len ); 355 | 356 | 357 | /*! 358 | * Mark a downloaded update file as "ready to install". 359 | * 360 | * Until the update is explicitly marked as such, the bootloader will ignore it! 361 | * 362 | * This feature allows for control when the actual installation is performed, 363 | * not just on the next reset after downloading. 364 | * 365 | * Note: To have the patch engine automatically mark the update as "ready to install" 366 | * use the initialization parameter: SE_PATCH_RebootDelay_NEXT. 367 | * To have the patch engine automatically mark the update as "ready to install" 368 | * *and* immediately reboot, use the initialization parameter: SE_PATCH_RebootDelay_IMMEDIATE. 369 | * 370 | * @Return SUCCESS if the image was marked, false otherwise. 371 | */ 372 | SE_ErrorStatus SE_PATCH_InstallAtNextReset(SE_PATCH_Status* status); 373 | 374 | 375 | /*! 376 | * Abort the update in progress. Return the state machine to IDLE. 377 | * 378 | * If necessary, abort will cause the firmware update image that was written to the 379 | * current update section to be invalidated before returning. 380 | * 381 | * This is a blocking call and may involve non-volatile write or erase operations. 382 | * 383 | * Abort will always return the updater state to IDLE. However, errors invalidating 384 | * the non-volatile memory can be detected by inspecting the returned status codes: 385 | * @p(blist) 386 | * - StatusCode_SECTION_ERASE_FAILURE: could not invalidate image. 387 | * if an image was successfully written, upon next reboot the bootloader will 388 | * attempt to install it but only if it verifies successfully. 389 | * (otherwise the currently running firmware image is booted again). 390 | * @p 391 | * @param(status) Supplied structure to be filled in with detailed API result status. 392 | * 393 | * @return SUCCESS if the abort completed, ERROR otherwise. 394 | */ 395 | SE_ErrorStatus SE_PATCH_Abort(SE_PATCH_Status* status); 396 | 397 | 398 | /*! 399 | * Get the current update status. 400 | * 401 | * Fill in the provided status structure. 402 | * The completed flag is set only when the update image has been written 403 | * to flash and verified, and the device has not rebooted yet. 404 | * 405 | * The error flag and status codes are set according to the result of the 406 | * last API call. 407 | * 408 | * @param(status) Supplied structure to be filled in with detailed API result status. 409 | * 410 | * @return SUCCESS if the status was returned in the provided structure, ERROR otherwise. 411 | */ 412 | SE_ErrorStatus SE_PATCH_Poll(SE_PATCH_Status* status); 413 | 414 | 415 | /*! 416 | * Get a string discription of the specified status code. 417 | * Return string, or empty string if code has no string 418 | * or strings no compiled in. 419 | */ 420 | const char* SE_PATCH_GetStatusCodeString(SE_PATCH_StatusCode code); 421 | 422 | 423 | 424 | #define SE_TAG_LEN (32) /* SHA-256 hash of FW image */ 425 | 426 | 427 | /** 428 | * @brief Firmware Information structure definition. 429 | * This structure is used to retrieve some information 430 | * about the active Firmware. 431 | */ 432 | typedef struct 433 | { 434 | uint32_t ActiveFwVersion; /*!< Firmware version (see @ref SFU_FW_VERSION_START_NUM for the min. valid value) */ 435 | uint32_t ActiveFwSize; /*!< Firmware size (bytes) */ 436 | uint8_t ActiveFwTag[SE_TAG_LEN]; /*!< Firmware Tag*/ 437 | } SE_APP_ActiveFwInfo; 438 | 439 | /* Extract version components "major", "minor" and "patch" from the 32-bit version field. 440 | * The version field should contain a value formatted such that major is the high bytes; minor is the middle short and 441 | * patch is the low byte. 442 | * Without any explicit formatting of this field, the version numbers will simply ramp 443 | * patch from 0 to 255 then minor from 0-65535 then major from 0-255. 444 | * E.g. a version of "452" would show as "0.1.196". 445 | * Note that any use of version field within the bootloader (e.g. anti-rollback feature) is 446 | * not impacted by specific formatting as long as a versions are always incrementing, 447 | * e.g. v1.12.0 is considered greater than v0.15.1 448 | */ 449 | #define FW_VERSION_MAJOR(x) (((uint32_t)(x) >> 24) & 0x000000FF) 450 | #define FW_VERSION_MINOR(x) (((uint32_t)(x) >> 8) & 0x0000FFFF) 451 | #define FW_VERSION_PATCH(x) (((uint32_t)(x) >> 0) & 0x000000FF) 452 | 453 | SE_ErrorStatus SE_APP_GetActiveFwInfo(SE_StatusTypeDef* peSE_Status, SE_APP_ActiveFwInfo* p_FwInfo); 454 | 455 | /* Copy the pre-provisoned secure user data into the provided pointer buffer. 456 | * This is an OTP area inside the bootloader flash area containing a maximum of 128 bytes. 457 | */ 458 | SE_ErrorStatus SE_APP_GetSecureUserData(SE_StatusTypeDef* peSE_Status, void* p_Data, uint32_t len); 459 | 460 | /* Get the bootloader version as a string in the format "v.." e.g. "v1.2.0" 461 | * The buffer is always null-terminated when the function returns. 462 | * A user buffer of at least 16 bytes is suggested. A buffer smaller than the bootloader version string length 463 | * will simply contain a truncated null-terminated string. 464 | * 465 | * @param p_Data buffer to copy bootloader version string into. 466 | * @param len length of provided buffer. 467 | */ 468 | SE_ErrorStatus SE_APP_GetBootVer(SE_StatusTypeDef* peSE_Status, char* p_Data, uint32_t len); 469 | 470 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/LICENSE.md -------------------------------------------------------------------------------- /Libs/B-L072Z-LRWAN1/stm32-secure-patching-bootloader-README_B-L072Z-LRWAN1_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | Total flash: 192 KB 4 | ------------------------------------------------------------------ 5 | | SBSFU | SLOT0 | SLOT1 | 6 | ------------------------------------------------------------------ 7 | 56 (14) 68 (17) 68 (17) 8 | 9 | YMODEM loader: YES 10 | UART1 115200,8,N,1 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Libs/B-L072Z-LRWAN1/stm32-secure-patching-bootloader-linker-gcc_B-L072Z-LRWAN1_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08006e00; 2 | SE_APP_GetBootVer = 0x08006e98; 3 | SE_APP_GetSecureUserData = 0x08006e4c; 4 | SE_APP_SVC_Handler = 0x08006e44; 5 | SE_PATCH_Abort = 0x0800789c; 6 | SE_PATCH_Data = 0x080077f0; 7 | SE_PATCH_Init = 0x080077a0; 8 | SE_PATCH_InitStatus = 0x08007784; 9 | SE_PATCH_InstallAtNextReset = 0x08007848; 10 | SE_PATCH_Poll = 0x08007890; 11 | SE_PATCH_PrintStatus = 0x08007794; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001500; 13 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x0801efff; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x0800e000; 15 | VECTOR_SIZE = 0x00000200; 16 | -------------------------------------------------------------------------------- /Libs/B-L072Z-LRWAN1/stm32-secure-patching-bootloader-postbuild_B-L072Z-LRWAN1_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/B-L072Z-LRWAN1/stm32-secure-patching-bootloader_B-L072Z-LRWAN1_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/B-L072Z-LRWAN1/stm32-secure-patching-bootloader_B-L072Z-LRWAN1_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/B-L072Z-LRWAN1/stm32-secure-patching-bootloader_B-L072Z-LRWAN1_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | c2e0bb48a1346dbf8d3ae59a8ce7bdc37c3b31ef58bd5a6cca42377d1ae64953 stm32-secure-patching-bootloader_B-L072Z-LRWAN1_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/B-L4S5I-IOT01A/stm32-secure-patching-bootloader-README_B-L4S5I-IOT01A_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 2 MB flash device. 4 | * internal sector size: 4K (dual bank mode - default) 5 | * 6 | * STM32L4S5 Internal flash 7 | * -------------------------------------------- ------------------- 8 | * | SBSFU | SLOT 0 | SLOT1 | 9 | * ---------------------------------------------------------------- 10 | * 80 984 984 11 | * 12 | * 0x08000000 13 | * 0x08014000 14 | * 0x08109FFF 15 | * 0x0810A000 16 | * 17 | * 0x081FFFFF 18 | */ 19 | 20 | | Feature | B-L4S5I-IOT01A | 21 | | --- | --- | 22 | | NAME | B-L4S5I-IOT01A 23 | | UART | USART1 TX:PB6 RX:PB7 AF7 115200,8,N,1 24 | | BUTTON | PC13 ACTIVE LOW 25 | | LED | GREEN/LED2/PB14 26 | | FLASH | 2048 27 | | RAM | 640 (192 SRAM1 + 64 SRAM2 + 384 SRAM3) 28 | | DEVID | 0x470 29 | | CLK | MSI,40,120,HSI48 30 | | YMODEM | YES 31 | | USB | NO "User must add 8 MHz crystal at X1 to use USB OTG" 32 | | EXT FLASH | NO 33 | | MULTISEG | NO 34 | | Product | https://www.st.com/en/evaluation-tools/b-l4s5i-iot01a.html 35 | 36 | -------------------------------------------------------------------------------- /Libs/B-L4S5I-IOT01A/stm32-secure-patching-bootloader-linker-gcc_B-L4S5I-IOT01A_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08007500; 2 | SE_APP_GetBootVer = 0x0800758c; 3 | SE_APP_GetSecureUserData = 0x08007544; 4 | SE_APP_SVC_Handler = 0x08007540; 5 | SE_PATCH_Abort = 0x0800804c; 6 | SE_PATCH_Data = 0x08007fa4; 7 | SE_PATCH_Init = 0x08007f54; 8 | SE_PATCH_InitStatus = 0x08007f3c; 9 | SE_PATCH_InstallAtNextReset = 0x08007ffc; 10 | SE_PATCH_Poll = 0x08008044; 11 | SE_PATCH_PrintStatus = 0x08007f48; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x08109fff; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08014000; 15 | VECTOR_SIZE = 0x00000200; 16 | -------------------------------------------------------------------------------- /Libs/B-L4S5I-IOT01A/stm32-secure-patching-bootloader-postbuild_B-L4S5I-IOT01A_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/B-L4S5I-IOT01A/stm32-secure-patching-bootloader_B-L4S5I-IOT01A_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/B-L4S5I-IOT01A/stm32-secure-patching-bootloader_B-L4S5I-IOT01A_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/B-L4S5I-IOT01A/stm32-secure-patching-bootloader_B-L4S5I-IOT01A_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | 6ade98fd87bf27d16ee96792117867b0268135d8a8d31e558ef08a35fafc51b2 stm32-secure-patching-bootloader_B-L4S5I-IOT01A_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/DISCO-F469I/stm32-secure-patching-bootloader-README_DISCO-F469I_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Note: all flash configurations assume *dual bank* mode. 4 | The F469 2 MB device only operates in dual bank mode. 5 | The 1 MB device can operate in either single or dual bank. 6 | With dual bank mode, the internal flash sectors are not uniform however 7 | this is not a problem for the bootloader. 8 | */ 9 | 10 | /* Configuration for 2 MB flash device. 11 | * 12 | * internal sector size: 16,64,128K 13 | * external sector size: 64K 14 | * 15 | * To work with the limited external flash and the STM32469I-Discovery TouchGFX demo, 16 | * we allocate half, 8 MB, to SLOT1. Thus SLOT0 is also 8 MB and split up as 1 MB SEG0 and 7 MB SEG1. 17 | * The touchGFX app's QSPI section has to fit into 7 MB. The Demo app cuts out the "Bird Eat Coin" 18 | * Game2D images when TOUCHGFX_DISABLE_GAME2D is defined in STM32CubeIDE for C++ preprocessor. 19 | 20 | * Allocating 8 MB to SLOT0 and SLOT1. SLOT0 SEG1 holds the GUI assets assigned to "ExtFlashSection" area. 21 | * 22 | * STM32F469 Internal flash N25Q128A 16 MB external flash 23 | * ------------------------------------------- ------------------------------------------------ 24 | * | SBSFU | SLOT0 SEG 0 | Unused | | SLOT0 SEG 1 | U | SLOT1 | 25 | * ------------------------------------------- ------------------------------------------------ 26 | * 128 1024 7168 8192 27 | * 28 | * 29 | * 0x08000000 30 | * 0x08020000 31 | * 0x0811FFFF 32 | * 0x081FFFFF 33 | * 34 | * 0x90000000 35 | * 0x906FFFFF 36 | * 0x90400000 37 | * 0x90FFFFFF 38 | */ 39 | 40 | 41 | | Feature | DISCO-F469I | 42 | | --- | --- | 43 | | NAME | 32F469IDISCOVERY 44 | | STATUS | Active 45 | | UART | USART3 TX:PB10 RX:PB11 AF7 115200,8,N,1 46 | | BUTTON | PA0 ACTIVE HIGH 47 | | LED | GREEN/LED1/PG6 48 | | FLASH | 2048 49 | | RAM | 320 (160 SRAM1 + 32 SRAM2 + 128 SRAM3) 50 | | DEVID | 0x434 51 | | CLK | HSE,8,180 52 | | YMODEM | YES 53 | | USB | YES PWR: PB2 54 | | EXT FLASH | YES 128 Mb QUADSPI N25Q128A 55 | | MULTISEG | YES 0x90000000 (QUADSPI1) 56 | | Product | https://www.st.com/en/evaluation-tools/32f469idiscovery.html 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Libs/DISCO-F469I/stm32-secure-patching-bootloader-linker-gcc_DISCO-F469I_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08008800; 2 | SE_APP_GetBootVer = 0x0800888c; 3 | SE_APP_GetSecureUserData = 0x08008844; 4 | SE_APP_SVC_Handler = 0x08008840; 5 | SE_PATCH_Abort = 0x0800934c; 6 | SE_PATCH_Data = 0x080092a4; 7 | SE_PATCH_Init = 0x08009254; 8 | SE_PATCH_InitStatus = 0x0800923c; 9 | SE_PATCH_InstallAtNextReset = 0x080092fc; 10 | SE_PATCH_Poll = 0x08009344; 11 | SE_PATCH_PrintStatus = 0x08009248; 12 | STM32_SECURE_PATCHING_BOOTLOADER_MULTISEG_START = 0x90000000; 13 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20002700; 14 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_TOP = 0x20050000; 15 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x0811ffff; 16 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08020000; 17 | VECTOR_SIZE = 0x00000200; 18 | -------------------------------------------------------------------------------- /Libs/DISCO-F469I/stm32-secure-patching-bootloader-postbuild_DISCO-F469I_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0x90000000 6 | -------------------------------------------------------------------------------- /Libs/DISCO-F469I/stm32-secure-patching-bootloader_DISCO-F469I_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/DISCO-F469I/stm32-secure-patching-bootloader_DISCO-F469I_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/DISCO-F469I/stm32-secure-patching-bootloader_DISCO-F469I_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | 9e121afa57304ad004a65717f0bc8cb7571429d16297d54d0c87a6954dfe9b2e stm32-secure-patching-bootloader_DISCO-F469I_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/DISCO-F769I/stm32-secure-patching-bootloader-README_DISCO-F769I_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 2 MB flash device. 4 | * 5 | * internal sector size: 256K 6 | * external sector size: 64K 7 | * 8 | * STM32F7 Internal flash MX25L512G External flash 9 | * ----------------------------------------------- ------------------------------------------------- 10 | * | SBSFU | U | SLOT0 SEG0 7 sectors | | SLOT0 SEG1 X sectors | SLOT1 7 + X sectors | ... 11 | * ----------------------------------------------- ------------------------------------------------- 12 | * 128 128 1792 256*X 1792 + 256*X 13 | * 14 | * Offsets given X = 16 (4 MB SEG1) 15 | * 16 | * 0x08000000 17 | * 0x08020000 18 | * 0x08040000 19 | * 20 | * 0x081FFFFF 21 | * 0x90000000 22 | * 0x90400000 23 | * 0x909BFFFF 24 | * 25 | * 26 | * X - number of 256K sectors to assign to storing application resources in QSPI area. 27 | * U - unused/available sector 128K. 28 | * 29 | */ 30 | 31 | YMODEM loader: YES 32 | UART1 115200,8,N,1 33 | 34 | USB flash loader: YES 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Libs/DISCO-F769I/stm32-secure-patching-bootloader-linker-gcc_DISCO-F769I_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08008800; 2 | SE_APP_GetBootVer = 0x0800888c; 3 | SE_APP_GetSecureUserData = 0x08008844; 4 | SE_APP_SVC_Handler = 0x08008840; 5 | SE_PATCH_Abort = 0x0800934c; 6 | SE_PATCH_Data = 0x080092a4; 7 | SE_PATCH_Init = 0x08009254; 8 | SE_PATCH_InitStatus = 0x0800923c; 9 | SE_PATCH_InstallAtNextReset = 0x080092fc; 10 | SE_PATCH_Poll = 0x08009344; 11 | SE_PATCH_PrintStatus = 0x08009248; 12 | STM32_SECURE_PATCHING_BOOTLOADER_MULTISEG_START = 0x90000000; 13 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20022700; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x081fffff; 15 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08040000; 16 | VECTOR_SIZE = 0x00000400; 17 | -------------------------------------------------------------------------------- /Libs/DISCO-F769I/stm32-secure-patching-bootloader-postbuild_DISCO-F769I_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=1024 4 | 5 | MultiSegAddr=0x90000000 6 | -------------------------------------------------------------------------------- /Libs/DISCO-F769I/stm32-secure-patching-bootloader_DISCO-F769I_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/DISCO-F769I/stm32-secure-patching-bootloader_DISCO-F769I_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/DISCO-F769I/stm32-secure-patching-bootloader_DISCO-F769I_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | cd851bd03f2ee79455d1133aca63493460551ae0781c729f66d41b177d0078dd stm32-secure-patching-bootloader_DISCO-F769I_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/DISCO-H745I/stm32-secure-patching-bootloader-README_DISCO-H745I_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 2 MB flash device. 4 | * 5 | * internal sector size: 128K 6 | * external sector size: 64Kx2 = 128K 7 | * 8 | * STM32H745I Internal flash mt25tl01g External flash dual-die 256x2 Mb 9 | * ------------------------------------------- ----------------------------------------------------------- 10 | * | BOOT | SLOT0 SEG0 | | SLOT0 SEG1 | SLOT1 | Unused | 11 | * ------------------------------------------- ----------------------------------------------------------- 12 | * 128 1920 2176 4096 13 | * 14 | * 15 | * 0x08000000 16 | * 0x08020000 17 | * 0x081FFFFF 18 | * 0x90000000 19 | * 0x90220000 20 | * 0x90620000 21 | * 22 | * 23 | * 24 | */ 25 | 26 | | Feature | DISCO-H745I | 27 | | --- | --- | 28 | | NAME | STM32H745I-DISCO 29 | | STATUS | Active 30 | | UART | USART3 TX:PB10 RX:PB11 AF7 115200,8,N,1 31 | | BUTTON | B1 PC13 ACTIVE HIGH 32 | | LED | GREEN/LD7/USER2/PJ2 33 | | FLASH | 2048 KB (dual bank, contiguous) @ 0x08000000. 34 | | | Cortex-M7 default boot from @ 0x08000000 (bank1) 35 | | | Cortex-M4 default boot from @ 0x08100000 (bank2) 36 | | RAM | DTCM 128 KB @ 0x20000000 37 | | | AXI 512 KB @ 0x24000000 *BOOT runs and is resident here* 38 | | | SRAM1 128 KB @ 0x30000000 39 | | | SRAM2 128 KB @ 0x30020000 40 | | | SRAM3 32 KB @ 0x30040000 41 | | | SRAM4 64 KB @ 0x38000000 42 | | DEVID | 0x450 43 | | CLK | HSE,25,400 44 | | YMODEM | YES 45 | | USB | YES PWR: PA5 ACTIVE HIGH 46 | | EXT FLASH | YES 256+256 Mbit QUADSPI MT25TL01G dualmode configuration (stacked-die) 47 | | MULTISEG | YES 0x90000000 (QUADSPI) 48 | | Product | https://www.st.com/en/evaluation-tools/stm32h745i-disco.html 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Libs/DISCO-H745I/stm32-secure-patching-bootloader-linker-gcc_DISCO-H745I_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08008b00; 2 | SE_APP_GetBootVer = 0x08008b8c; 3 | SE_APP_GetSecureUserData = 0x08008b44; 4 | SE_APP_SVC_Handler = 0x08008b40; 5 | SE_PATCH_Abort = 0x0800964c; 6 | SE_PATCH_Data = 0x080095a4; 7 | SE_PATCH_Init = 0x08009554; 8 | SE_PATCH_InitStatus = 0x0800953c; 9 | SE_PATCH_InstallAtNextReset = 0x080095fc; 10 | SE_PATCH_Poll = 0x08009644; 11 | SE_PATCH_PrintStatus = 0x08009548; 12 | STM32_SECURE_PATCHING_BOOTLOADER_MULTISEG_START = 0x90000000; 13 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x24002700; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x081fffff; 15 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08020000; 16 | VECTOR_SIZE = 0x00000400; 17 | -------------------------------------------------------------------------------- /Libs/DISCO-H745I/stm32-secure-patching-bootloader-postbuild_DISCO-H745I_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=1024 4 | 5 | MultiSegAddr=0x90000000 6 | -------------------------------------------------------------------------------- /Libs/DISCO-H745I/stm32-secure-patching-bootloader_DISCO-H745I_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/DISCO-H745I/stm32-secure-patching-bootloader_DISCO-H745I_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/DISCO-H745I/stm32-secure-patching-bootloader_DISCO-H745I_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | f8263dcd986a2938e044ca97c1764c2f85a3f99c403e0592df268fcaac3eb867 stm32-secure-patching-bootloader_DISCO-H745I_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/DISCO-L476G/stm32-secure-patching-bootloader-README_DISCO-L476G_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 1 MB flash device, NO QSPI 4 | * 5 | * internal sector size: 2K 6 | * SBSFU is around 71K fully loaded with ALL debug output 7 | * 8 | * ------------------------------------------------------------------------ 9 | * | SBSFU | SLOT0 | SLOT1 | ... | 10 | * ------------------------------------------------------------------------ 11 | * 80 256 256 12 | * 13 | * 0x08000000 14 | * 0x08014000 15 | * 0x08054000 16 | * 0x08094000 17 | * 0x90400000 18 | */ 19 | 20 | YMODEM loader: YES 21 | UART2 115200,8,N,1 22 | 23 | USB flash loader: YES 24 | 25 | Note: built for REVB or REVC MB1184. 26 | 27 | -------------------------------------------------------------------------------- /Libs/DISCO-L476G/stm32-secure-patching-bootloader-linker-gcc_DISCO-L476G_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08007500; 2 | SE_APP_GetBootVer = 0x0800758c; 3 | SE_APP_GetSecureUserData = 0x08007544; 4 | SE_APP_SVC_Handler = 0x08007540; 5 | SE_PATCH_Abort = 0x0800804c; 6 | SE_PATCH_Data = 0x08007fa4; 7 | SE_PATCH_Init = 0x08007f54; 8 | SE_PATCH_InitStatus = 0x08007f3c; 9 | SE_PATCH_InstallAtNextReset = 0x08007ffc; 10 | SE_PATCH_Poll = 0x08008044; 11 | SE_PATCH_PrintStatus = 0x08007f48; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x08053fff; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08014000; 15 | VECTOR_SIZE = 0x00000200; 16 | -------------------------------------------------------------------------------- /Libs/DISCO-L476G/stm32-secure-patching-bootloader-postbuild_DISCO-L476G_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/DISCO-L476G/stm32-secure-patching-bootloader_DISCO-L476G_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/DISCO-L476G/stm32-secure-patching-bootloader_DISCO-L476G_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/DISCO-L476G/stm32-secure-patching-bootloader_DISCO-L476G_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | 42be52f61b71d9e285796af4cbdd167878829f4b3f29196a28d88b427e1967c9 stm32-secure-patching-bootloader_DISCO-L476G_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/DISCO-L496G/stm32-secure-patching-bootloader-README_DISCO-L496G_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 1 MB flash device, NO QSPI 4 | * 5 | * internal sector size: 2K 6 | * SBSFU is around 71K fully loaded with ALL debug output 7 | * 8 | * ------------------------------------------------------------------------ 9 | * | SBSFU | SLOT0 | SLOT1 | ... | 10 | * ------------------------------------------------------------------------ 11 | * 80 256 256 12 | * 13 | * 0x08000000 14 | * 0x08014000 15 | * 0x08054000 16 | * 0x08094000 17 | * 0x90400000 18 | * 19 | */ 20 | 21 | YMODEM loader: YES 22 | UART2 115200,8,N,1 23 | 24 | USB flash loader: YES 25 | 26 | -------------------------------------------------------------------------------- /Libs/DISCO-L496G/stm32-secure-patching-bootloader-linker-gcc_DISCO-L496G_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08007500; 2 | SE_APP_GetBootVer = 0x0800758c; 3 | SE_APP_GetSecureUserData = 0x08007544; 4 | SE_APP_SVC_Handler = 0x08007540; 5 | SE_PATCH_Abort = 0x0800804c; 6 | SE_PATCH_Data = 0x08007fa4; 7 | SE_PATCH_Init = 0x08007f54; 8 | SE_PATCH_InitStatus = 0x08007f3c; 9 | SE_PATCH_InstallAtNextReset = 0x08007ffc; 10 | SE_PATCH_Poll = 0x08008044; 11 | SE_PATCH_PrintStatus = 0x08007f48; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x08053fff; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08014000; 15 | VECTOR_SIZE = 0x00000200; 16 | -------------------------------------------------------------------------------- /Libs/DISCO-L496G/stm32-secure-patching-bootloader-postbuild_DISCO-L496G_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/DISCO-L496G/stm32-secure-patching-bootloader_DISCO-L496G_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/DISCO-L496G/stm32-secure-patching-bootloader_DISCO-L496G_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/DISCO-L496G/stm32-secure-patching-bootloader_DISCO-L496G_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | 44763c0f298686c2928f71cdebc965547f15e60a4691e6883cef33c2133e020e stm32-secure-patching-bootloader_DISCO-L496G_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/DISCO-L4R9I/stm32-secure-patching-bootloader-README_DISCO-L4R9I_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 2 MB flash device. 4 | * Flash: 512 Mb OCTOSPI MX25LM51245GXDI00 5 | * internal sector size: 4K (dual bank mode - default) 6 | * external sector size: 4K, 32K or 64K (64K used as block) 7 | * SBSFU is around 82K fully loaded with External flash/Multiseg + USB flash loader 8 | * 9 | * STM32L4R9 Internal flash MX25LM51245G 64 MB External flash 10 | * --------------------------------- ----------- ------------------------------------------------- 11 | * | SBSFU | SLOT 0 SEG0 | | SLOT0 SEG1 X sectors | SLOT1 | ... | 12 | * --------------------------------- --------------------------------------------------------------- 13 | * 84 1964 4096 1964 + 4096 14 | * 15 | * 16 | * 0x08000000 17 | * 0x08015000 18 | * 19 | * 0x081FFFFF 20 | * 0x90000000 21 | * 0x90400000 22 | * 0x909EAFFF 23 | * 0x909EB000 24 | * 25 | */ 26 | 27 | | Feature | DISCO-L4R9I | 28 | | --- | --- | 29 | | NAME | 32L4R9IDISCOVERY 30 | | STATUS | Active (8-11-22) 31 | | UART | USART2 TX:PA2 RX:PA3 AF7 115200,8,N,1 32 | | BUTTON | (JOY-SEL) PC13 ACTIVE HIGH 33 | | LED | GREEN/LED2/PH4 34 | | FLASH | 2048 35 | | RAM | 640 (192 SRAM1 + 64 SRAM2 + 384 SRAM3) 36 | | DEVID | 0x470 37 | | CLK | MSI,40,120,HSI48 38 | | YMODEM | YES 39 | | USB | YES PWR: MFX_GPIO13 40 | | EXT FLASH | YES 512 Mb OCTOSPI MX25LM51245GXDI00 41 | | MULTISEG | YES 0x90000000 (OCTOSPI1) 42 | | Product | https://www.st.com/en/evaluation-tools/32l4r9idiscovery.html 43 | -------------------------------------------------------------------------------- /Libs/DISCO-L4R9I/stm32-secure-patching-bootloader-linker-gcc_DISCO-L4R9I_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08007500; 2 | SE_APP_GetBootVer = 0x0800758c; 3 | SE_APP_GetSecureUserData = 0x08007544; 4 | SE_APP_SVC_Handler = 0x08007540; 5 | SE_PATCH_Abort = 0x0800804c; 6 | SE_PATCH_Data = 0x08007fa4; 7 | SE_PATCH_Init = 0x08007f54; 8 | SE_PATCH_InitStatus = 0x08007f3c; 9 | SE_PATCH_InstallAtNextReset = 0x08007ffc; 10 | SE_PATCH_Poll = 0x08008044; 11 | SE_PATCH_PrintStatus = 0x08007f48; 12 | STM32_SECURE_PATCHING_BOOTLOADER_MULTISEG_START = 0x90000000; 13 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x081fffff; 15 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08015000; 16 | VECTOR_SIZE = 0x00000200; 17 | -------------------------------------------------------------------------------- /Libs/DISCO-L4R9I/stm32-secure-patching-bootloader-postbuild_DISCO-L4R9I_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0x90000000 6 | -------------------------------------------------------------------------------- /Libs/DISCO-L4R9I/stm32-secure-patching-bootloader_DISCO-L4R9I_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/DISCO-L4R9I/stm32-secure-patching-bootloader_DISCO-L4R9I_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/DISCO-L4R9I/stm32-secure-patching-bootloader_DISCO-L4R9I_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | e24c9e4c6896c6807896cce873cb558aa959c362460a7a96b1dbb6152c387b4f stm32-secure-patching-bootloader_DISCO-L4R9I_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/DISCO-L562E/stm32-secure-patching-bootloader-README_DISCO-L562E_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | * STM32L5 Internal flash 512 KB 4 | * ------------------------------------------------- 5 | * | SBSFU | U | SLOT0 | SLOT1 | 6 | * ------------------------------------------------- 7 | * 64 64 192 192 8 | * 9 | * 0x08000000 10 | * 0x08010000 11 | * 0x08020000 12 | * 0x0804FFFF 13 | * 0x08050000 14 | * 0x0807FFFF 15 | * 16 | * U - unused/available sector(s) 17 | 18 | 19 | | Feature | DISCO-L562E | 20 | | --- | --- | 21 | | NAME | STM32L562E-DK 22 | | UART | USART1 TX:PA9 RX:PA10 AF7 115200,8,N,1 23 | | BUTTON | PC13 ACTIVE HIGH 24 | | LED | GREEN/LED10/PG12 25 | | FLASH | 512 26 | | RAM | 256 (192 SRAM1 + 64 SRAM2) 27 | | DEVID | 0x472 28 | | CLK | MSI,4,110 29 | | YMODEM | YES 30 | | USB | NO "The STM32L562E-DK Discovery kit supports USB Type-C sink mode only." 31 | | EXT FLASH | NO 32 | | MULTISEG | NO 33 | | Product | https://www.st.com/en/evaluation-tools/stm32l562e-dk.html 34 | 35 | -------------------------------------------------------------------------------- /Libs/DISCO-L562E/stm32-secure-patching-bootloader-linker-gcc_DISCO-L562E_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08007500; 2 | SE_APP_GetBootVer = 0x0800758c; 3 | SE_APP_GetSecureUserData = 0x08007544; 4 | SE_APP_SVC_Handler = 0x08007540; 5 | SE_PATCH_Abort = 0x0800804c; 6 | SE_PATCH_Data = 0x08007fa4; 7 | SE_PATCH_Init = 0x08007f54; 8 | SE_PATCH_InitStatus = 0x08007f3c; 9 | SE_PATCH_InstallAtNextReset = 0x08007ffc; 10 | SE_PATCH_Poll = 0x08008044; 11 | SE_PATCH_PrintStatus = 0x08007f48; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x0804ffff; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08020000; 15 | VECTOR_SIZE = 0x00000200; 16 | -------------------------------------------------------------------------------- /Libs/DISCO-L562E/stm32-secure-patching-bootloader-postbuild_DISCO-L562E_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/DISCO-L562E/stm32-secure-patching-bootloader_DISCO-L562E_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/DISCO-L562E/stm32-secure-patching-bootloader_DISCO-L562E_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/DISCO-L562E/stm32-secure-patching-bootloader_DISCO-L562E_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | 1c523a1dc0e1aac5b3dc1353afdae83fcf0ec552bcbcde735df77dcf7eb23ff2 stm32-secure-patching-bootloader_DISCO-L562E_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/LORA-E5-DEV/stm32-secure-patching-bootloader-README_LORA-E5-DEV_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | Total flash: 256 KB 4 | 5 | ---------------------------------------------------------------------------- 6 | | SBSFU | SLOT0 | SLOT1 | User | 7 | ---------------------------------------------------------------------------- 8 | 48 102 102 4 9 | 10 | 0x08000000 11 | 0x0800C000 12 | 0x08025800 13 | 0x0803F000 14 | 0x08040000 15 | 16 | YMODEM loader: YES 17 | UART1 115200,8,N,1 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Libs/LORA-E5-DEV/stm32-secure-patching-bootloader-linker-gcc_LORA-E5-DEV_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08006600; 2 | SE_APP_GetBootVer = 0x0800668c; 3 | SE_APP_GetSecureUserData = 0x08006644; 4 | SE_APP_SVC_Handler = 0x08006640; 5 | SE_PATCH_Abort = 0x08007148; 6 | SE_PATCH_Data = 0x080070a0; 7 | SE_PATCH_Init = 0x08007050; 8 | SE_PATCH_InitStatus = 0x08007038; 9 | SE_PATCH_InstallAtNextReset = 0x080070f8; 10 | SE_PATCH_Poll = 0x08007140; 11 | SE_PATCH_PrintStatus = 0x08007044; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_TOP = 0x20010000; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x080257ff; 15 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x0800c000; 16 | VECTOR_SIZE = 0x00000200; 17 | -------------------------------------------------------------------------------- /Libs/LORA-E5-DEV/stm32-secure-patching-bootloader-postbuild_LORA-E5-DEV_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/LORA-E5-DEV/stm32-secure-patching-bootloader_LORA-E5-DEV_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/LORA-E5-DEV/stm32-secure-patching-bootloader_LORA-E5-DEV_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/LORA-E5-DEV/stm32-secure-patching-bootloader_LORA-E5-DEV_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | 33f7561aab8f2cdec11dda18a43a752b32cd160850833a4bf1055bfb350ad8a3 stm32-secure-patching-bootloader_LORA-E5-DEV_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/NUCLEO-F429ZI/stm32-secure-patching-bootloader-README_NUCLEO-F429ZI_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 2 MB flash device. 4 | * *SINGLE BANK MODE* 5 | * 6 | * internal sector size: 128K 7 | * 8 | * Only allocate 256K for each slot. 9 | * 10 | * STM32F429 Internal flash 11 | * ------------------------------------------------------------------------------------------------ 12 | * | SBSFU | SLOT0 2 sectors | SLOT1 2 sectors | ... 13 | * ------------------------------------------------------------------------------------------------ 14 | * 128 256 256 15 | * 16 | * 17 | * 0x08000000 18 | * 0x08020000 19 | * 20 | * 0x085FFFFF 21 | * 0x08060000 22 | * 0x0809FFFF 23 | 24 | | Feature | NUCLEO-F429ZI | 25 | | --- | --- | 26 | | NAME | NUCLEO-F429ZI 27 | | STATUS | Active 28 | | UART | USART3 TX:PD8 RX:PD9 AF7 115200,8,N,1 29 | | BUTTON | PC13 ACTIVE HIGH 30 | | LED | GREEN/LED1/PC7 31 | | FLASH | 2048 32 | | RAM | 192 33 | | DEVID | 0x419 34 | | CLK | HSE,8,168 35 | | YMODEM | YES 36 | | USB | YES PWR: PG6 ACTIVE LOW 37 | | EXT FLASH | NO 38 | | MULTISEG | NO 39 | | Product | https://www.st.com/en/evaluation-tools/nucleo-f429zi.html 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Libs/NUCLEO-F429ZI/stm32-secure-patching-bootloader-linker-gcc_NUCLEO-F429ZI_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08006700; 2 | SE_APP_GetBootVer = 0x0800678c; 3 | SE_APP_GetSecureUserData = 0x08006744; 4 | SE_APP_SVC_Handler = 0x08006740; 5 | SE_PATCH_Abort = 0x0800724c; 6 | SE_PATCH_Data = 0x080071a4; 7 | SE_PATCH_Init = 0x08007154; 8 | SE_PATCH_InitStatus = 0x0800713c; 9 | SE_PATCH_InstallAtNextReset = 0x080071fc; 10 | SE_PATCH_Poll = 0x08007244; 11 | SE_PATCH_PrintStatus = 0x08007148; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20002700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x0805ffff; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08020000; 15 | VECTOR_SIZE = 0x00000200; 16 | -------------------------------------------------------------------------------- /Libs/NUCLEO-F429ZI/stm32-secure-patching-bootloader-postbuild_NUCLEO-F429ZI_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/NUCLEO-F429ZI/stm32-secure-patching-bootloader_NUCLEO-F429ZI_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/NUCLEO-F429ZI/stm32-secure-patching-bootloader_NUCLEO-F429ZI_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/NUCLEO-F429ZI/stm32-secure-patching-bootloader_NUCLEO-F429ZI_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | 2a0922d80a94cfe9134b9e1475b892fe623e95f80022fea992ea1f57b7c1d34d stm32-secure-patching-bootloader_NUCLEO-F429ZI_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/NUCLEO-G0B1RE/stm32-secure-patching-bootloader-README_NUCLEO-G0B1RE_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 512 KB flash device 4 | * 5 | * Internal erase and write protection sector size: 2K 6 | * Setup slot sizing for the debug mode on 2K boundaries. 7 | * 8 | * ------------------------------------------------------------------ 9 | * | SBSFU | SLOT0 | SLOT1 | 10 | * ------------------------------------------------------------------ 11 | * 64 224 224 12 | * 13 | * 0x08000000 14 | * 0x08010000 15 | * 0x08047FFF 16 | * 0x08048000 17 | * 0x0807FFFF 18 | * 19 | */ 20 | 21 | 22 | | Feature | NUCLEO-G0B1RE | 23 | | --- | --- | 24 | | NAME | NUCLEO-G0B1RE 25 | | UART | USART2 TX:PA2 RX:PA3 115200,8,N,1 26 | | BUTTON | PC13 ACTIVE LOW 27 | | LED | GREEN/LED2/PA5 28 | | FLASH | 512 29 | | RAM | 144 (no parity check) 30 | | DEVID | 0x467 31 | | CLK | HSI,64 32 | | YMODEM | YES, button trigger, 'load' trigger 33 | | USB | NO 34 | | EXT FLASH | NO 35 | | MULTISEG | NO 36 | | Product | https://www.st.com/en/evaluation-tools/nucleo-g0b1re.html 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Libs/NUCLEO-G0B1RE/stm32-secure-patching-bootloader-linker-gcc_NUCLEO-G0B1RE_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08008000; 2 | SE_APP_GetBootVer = 0x08008098; 3 | SE_APP_GetSecureUserData = 0x0800804c; 4 | SE_APP_SVC_Handler = 0x08008044; 5 | SE_PATCH_Abort = 0x08008a9c; 6 | SE_PATCH_Data = 0x080089f0; 7 | SE_PATCH_Init = 0x080089a0; 8 | SE_PATCH_InitStatus = 0x08008984; 9 | SE_PATCH_InstallAtNextReset = 0x08008a48; 10 | SE_PATCH_Poll = 0x08008a90; 11 | SE_PATCH_PrintStatus = 0x08008994; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_TOP = 0x20024000; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x08047fff; 15 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08010000; 16 | VECTOR_SIZE = 0x00000200; 17 | -------------------------------------------------------------------------------- /Libs/NUCLEO-G0B1RE/stm32-secure-patching-bootloader-postbuild_NUCLEO-G0B1RE_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/NUCLEO-G0B1RE/stm32-secure-patching-bootloader_NUCLEO-G0B1RE_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/NUCLEO-G0B1RE/stm32-secure-patching-bootloader_NUCLEO-G0B1RE_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/NUCLEO-G0B1RE/stm32-secure-patching-bootloader_NUCLEO-G0B1RE_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | 27e337dfedb40b4d3c804ab039fd0b225875648becf4be1a22570b2a91a74a06 stm32-secure-patching-bootloader_NUCLEO-G0B1RE_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L073RZ/stm32-secure-patching-bootloader-README_NUCLEO-L073RZ_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 192 KB flash device 4 | * 5 | * Internal write protection sector size: 4K, erase page is 128 bytes. 6 | * Setup slot sizing for the debug mode on 4K boundaries. 7 | * 8 | * ------------------------------------------------------------------ 9 | * | SBSFU | SLOT0 | SLOT1 | 10 | * ------------------------------------------------------------------ 11 | * 56 (14) 68 (17) 68 (17) 12 | * 13 | * 0x08000000 14 | * 0x0800E000 15 | * 0x0801F000 16 | * 0x0802FFFF 17 | * 18 | */ 19 | 20 | 21 | | Feature | NUCLEO-L073RZ | 22 | | --- | --- | 23 | | NAME | NUCLEO-L073RZ 24 | | UART | USART2 TX:PA2 RX:PA3 AF4 115200,8,N,1 25 | | BUTTON | PC13 ACTIVE LOW 26 | | LED | GREEN/LED2/PA5 27 | | FLASH | 192 28 | | RAM | 20 29 | | DEVID | 0x447 30 | | CLK | HSI,32 31 | | YMODEM | YES 32 | | USB | NO 33 | | EXT FLASH | NO 34 | | MULTISEG | NO 35 | | Product | https://www.st.com/en/evaluation-tools/nucleo-l073rz.html 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L073RZ/stm32-secure-patching-bootloader-linker-gcc_NUCLEO-L073RZ_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08006e00; 2 | SE_APP_GetBootVer = 0x08006e98; 3 | SE_APP_GetSecureUserData = 0x08006e4c; 4 | SE_APP_SVC_Handler = 0x08006e44; 5 | SE_PATCH_Abort = 0x0800789c; 6 | SE_PATCH_Data = 0x080077f0; 7 | SE_PATCH_Init = 0x080077a0; 8 | SE_PATCH_InitStatus = 0x08007784; 9 | SE_PATCH_InstallAtNextReset = 0x08007848; 10 | SE_PATCH_Poll = 0x08007890; 11 | SE_PATCH_PrintStatus = 0x08007794; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001500; 13 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x0801efff; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x0800e000; 15 | VECTOR_SIZE = 0x00000200; 16 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L073RZ/stm32-secure-patching-bootloader-postbuild_NUCLEO-L073RZ_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L073RZ/stm32-secure-patching-bootloader_NUCLEO-L073RZ_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/NUCLEO-L073RZ/stm32-secure-patching-bootloader_NUCLEO-L073RZ_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/NUCLEO-L073RZ/stm32-secure-patching-bootloader_NUCLEO-L073RZ_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | 0f5bfb90affa769226bd6c31f729577424919c01416585e8de082c9d57423013 stm32-secure-patching-bootloader_NUCLEO-L073RZ_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L412KB/stm32-secure-patching-bootloader-README_NUCLEO-L412KB_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 128 KB flash device, NO QSPI 4 | * 5 | * Internal sector size: 2K 6 | * 7 | * Single slot mode (no patch file .sfbp support) 8 | * 9 | * ------------------------------------------- 10 | * | SBSFU | SLOT0 | 11 | * ------------------------------------------- 12 | * 64 64 13 | * 14 | * 0x08000000 15 | * 0x08010000 16 | * 0x08020000 17 | * 18 | */ 19 | 20 | YMODEM loader: YES 21 | UART2 115200,8,N,1 22 | 23 | USB flash loader: NO 24 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L412KB/stm32-secure-patching-bootloader-linker-gcc_NUCLEO-L412KB_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08007500; 2 | SE_APP_GetBootVer = 0x0800758c; 3 | SE_APP_GetSecureUserData = 0x08007544; 4 | SE_APP_SVC_Handler = 0x08007540; 5 | SE_PATCH_Abort = 0x0800804c; 6 | SE_PATCH_Data = 0x08007fa4; 7 | SE_PATCH_Init = 0x08007f54; 8 | SE_PATCH_InitStatus = 0x08007f3c; 9 | SE_PATCH_InstallAtNextReset = 0x08007ffc; 10 | SE_PATCH_Poll = 0x08008044; 11 | SE_PATCH_PrintStatus = 0x08007f48; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x0801ffff; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08010000; 15 | VECTOR_SIZE = 0x00000200; 16 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L412KB/stm32-secure-patching-bootloader-postbuild_NUCLEO-L412KB_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L412KB/stm32-secure-patching-bootloader_NUCLEO-L412KB_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/NUCLEO-L412KB/stm32-secure-patching-bootloader_NUCLEO-L412KB_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/NUCLEO-L412KB/stm32-secure-patching-bootloader_NUCLEO-L412KB_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | b3806ad47f97353690e1425a97b3f624bce65241e853b948abb431664e4cf40f stm32-secure-patching-bootloader_NUCLEO-L412KB_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L452RE/stm32-secure-patching-bootloader-README_NUCLEO-L452RE_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 512 KB flash device, NO QSPI 4 | * 5 | * Internal sector size: 2K 6 | * 7 | * ------------------------------------------------------------------------ 8 | * | SBSFU | SLOT0 | SLOT1 | Rsvd | 9 | * ------------------------------------------------------------------------ 10 | * 64 128 128 192 11 | * 12 | * 0x08000000 13 | * 0x08010000 14 | * 0x08030000 15 | * 0x08050000 16 | * 0x80080000 17 | * 18 | */ 19 | 20 | YMODEM loader: YES 21 | UART2 115200,8,N,1 22 | 23 | USB flash loader: NO 24 | 25 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L452RE/stm32-secure-patching-bootloader-linker-gcc_NUCLEO-L452RE_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08007500; 2 | SE_APP_GetBootVer = 0x0800758c; 3 | SE_APP_GetSecureUserData = 0x08007544; 4 | SE_APP_SVC_Handler = 0x08007540; 5 | SE_PATCH_Abort = 0x0800804c; 6 | SE_PATCH_Data = 0x08007fa4; 7 | SE_PATCH_Init = 0x08007f54; 8 | SE_PATCH_InitStatus = 0x08007f3c; 9 | SE_PATCH_InstallAtNextReset = 0x08007ffc; 10 | SE_PATCH_Poll = 0x08008044; 11 | SE_PATCH_PrintStatus = 0x08007f48; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x0802ffff; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08010000; 15 | VECTOR_SIZE = 0x00000200; 16 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L452RE/stm32-secure-patching-bootloader-postbuild_NUCLEO-L452RE_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L452RE/stm32-secure-patching-bootloader_NUCLEO-L452RE_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/NUCLEO-L452RE/stm32-secure-patching-bootloader_NUCLEO-L452RE_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/NUCLEO-L452RE/stm32-secure-patching-bootloader_NUCLEO-L452RE_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | 2dec025a265236bae4379fa352198599f92aaa002591c246eaec111c600216b6 stm32-secure-patching-bootloader_NUCLEO-L452RE_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L476RG/stm32-secure-patching-bootloader-README_NUCLEO-L476RG_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 1 MB flash device STM32L476RG 4 | * 5 | * Internal sector size: 2K 6 | * 7 | * ------------------------------------------------------------------------ 8 | * | SBSFU | SLOT0 | SLOT1 | ... | 9 | * ------------------------------------------------------------------------ 10 | * 80 256 256 11 | * 12 | * 0x08000000 13 | * 0x08014000 14 | * 0x08054000 15 | * 0x08094000 16 | */ 17 | 18 | Note: built for MB1136 C-02 or C-03 with LSE. 19 | 20 | | Feature | NUCLEO-L476RG | 21 | | --- | --- | 22 | | NAME | NUCLEO-L476RG 23 | | UART | USART2 TX:PA2 RX:PA3 115200,8,N,1 24 | | BUTTON | PC13 ACTIVE LOW 25 | | LED | GREEN/LED2/PA5 ACTIVE HIGH 26 | | FLASH | 1024 27 | | RAM | 96 28 | | DEVID | 0x415 29 | | CLK | MSI,4,80 30 | | YMODEM | YES, button trigger, 'load' trigger 31 | | USB | NO 32 | | EXT FLASH | NO 33 | | MULTISEG | NO 34 | | Product | https://www.st.com/en/evaluation-tools/nucleo-l476rg.html 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L476RG/stm32-secure-patching-bootloader-linker-gcc_NUCLEO-L476RG_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08007500; 2 | SE_APP_GetBootVer = 0x0800758c; 3 | SE_APP_GetSecureUserData = 0x08007544; 4 | SE_APP_SVC_Handler = 0x08007540; 5 | SE_PATCH_Abort = 0x0800804c; 6 | SE_PATCH_Data = 0x08007fa4; 7 | SE_PATCH_Init = 0x08007f54; 8 | SE_PATCH_InitStatus = 0x08007f3c; 9 | SE_PATCH_InstallAtNextReset = 0x08007ffc; 10 | SE_PATCH_Poll = 0x08008044; 11 | SE_PATCH_PrintStatus = 0x08007f48; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x08053fff; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08014000; 15 | VECTOR_SIZE = 0x00000200; 16 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L476RG/stm32-secure-patching-bootloader-postbuild_NUCLEO-L476RG_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L476RG/stm32-secure-patching-bootloader_NUCLEO-L476RG_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/NUCLEO-L476RG/stm32-secure-patching-bootloader_NUCLEO-L476RG_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/NUCLEO-L476RG/stm32-secure-patching-bootloader_NUCLEO-L476RG_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | 174762381eff47fec96ab5c4d7653ca387fc4fe6338da24889beaff0fd50c1b2 stm32-secure-patching-bootloader_NUCLEO-L476RG_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L496ZG/stm32-secure-patching-bootloader-README_NUCLEO-L496ZG_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | /* Configuration for 1 MB flash device, NO QSPI 4 | * 5 | * internal sector size: 2K 6 | * SBSFU is around 71K fully loaded with ALL debug output 7 | * 8 | * ------------------------------------------------------------------------ 9 | * | SBSFU | SLOT0 | SLOT1 | ... | 10 | * ------------------------------------------------------------------------ 11 | * 80 256 256 12 | * 13 | * 0x08000000 14 | * 0x08014000 15 | * 0x08054000 16 | * 0x08094000 17 | * 0x90400000 18 | * 19 | */ 20 | 21 | YMODEM loader: YES 22 | UART1 115200,8,N,1 23 | 24 | USB flash loader: YES 25 | 26 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L496ZG/stm32-secure-patching-bootloader-linker-gcc_NUCLEO-L496ZG_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08007500; 2 | SE_APP_GetBootVer = 0x0800758c; 3 | SE_APP_GetSecureUserData = 0x08007544; 4 | SE_APP_SVC_Handler = 0x08007540; 5 | SE_PATCH_Abort = 0x0800804c; 6 | SE_PATCH_Data = 0x08007fa4; 7 | SE_PATCH_Init = 0x08007f54; 8 | SE_PATCH_InitStatus = 0x08007f3c; 9 | SE_PATCH_InstallAtNextReset = 0x08007ffc; 10 | SE_PATCH_Poll = 0x08008044; 11 | SE_PATCH_PrintStatus = 0x08007f48; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x08053fff; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x08014000; 15 | VECTOR_SIZE = 0x00000200; 16 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L496ZG/stm32-secure-patching-bootloader-postbuild_NUCLEO-L496ZG_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/NUCLEO-L496ZG/stm32-secure-patching-bootloader_NUCLEO-L496ZG_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/NUCLEO-L496ZG/stm32-secure-patching-bootloader_NUCLEO-L496ZG_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/NUCLEO-L496ZG/stm32-secure-patching-bootloader_NUCLEO-L496ZG_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | bb3ac0e5562af90b2a4af3bb6e67aac74b69d1165fdce8b5cc624ee969efc107 stm32-secure-patching-bootloader_NUCLEO-L496ZG_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/NUCLEO-WL55JC/stm32-secure-patching-bootloader-README_NUCLEO-WL55JC_v1.4.0.txt: -------------------------------------------------------------------------------- 1 | # Board configuration 2 | 3 | Total flash: 256 KB 4 | 5 | * ---------------------------------------------------------------------------- 6 | * | SBSFU | SLOT0 | SLOT1 | 7 | * ---------------------------------------------------------------------------- 8 | * 56 100 100 9 | * 10 | * 0x08000000 11 | * 0x0800E000 12 | * 0x08027000 13 | * 14 | * 0x08040000 15 | 16 | | Feature | NUCLEO-WL55JC | 17 | | --- | --- | 18 | | NAME | NUCLEO-WL55JC 19 | | UART | LPUART1 TX:PA2 RX:PA3 115200,8,N,1 20 | | BUTTON | PA0 ACTIVE LOW 21 | | LED | GREEN/LED2/PB9 22 | | FLASH | 256 23 | | RAM | 64 24 | | DEVID | 0x497 25 | | CLK | MSI,4,48 26 | | YMODEM | YES, button trigger, 'load' trigger 27 | | USB | NO 28 | | EXT FLASH | NO 29 | | MULTISEG | NO 30 | | Product | https://www.st.com/en/evaluation-tools/nucleo-wl55jc.html 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Libs/NUCLEO-WL55JC/stm32-secure-patching-bootloader-linker-gcc_NUCLEO-WL55JC_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | SE_APP_GetActiveFwInfo = 0x08008000; 2 | SE_APP_GetBootVer = 0x0800808c; 3 | SE_APP_GetSecureUserData = 0x08008044; 4 | SE_APP_SVC_Handler = 0x08008040; 5 | SE_PATCH_Abort = 0x08008b48; 6 | SE_PATCH_Data = 0x08008aa0; 7 | SE_PATCH_Init = 0x08008a50; 8 | SE_PATCH_InitStatus = 0x08008a38; 9 | SE_PATCH_InstallAtNextReset = 0x08008af8; 10 | SE_PATCH_Poll = 0x08008b40; 11 | SE_PATCH_PrintStatus = 0x08008a44; 12 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_START = 0x20001700; 13 | STM32_SECURE_PATCHING_BOOTLOADER_RAM_TOP = 0x20010000; 14 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END = 0x08026fff; 15 | STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START = 0x0800e000; 16 | VECTOR_SIZE = 0x00000200; 17 | -------------------------------------------------------------------------------- /Libs/NUCLEO-WL55JC/stm32-secure-patching-bootloader-postbuild_NUCLEO-WL55JC_v1.4.0.sh: -------------------------------------------------------------------------------- 1 | # Board-specific properties injected into the postbuild.sh script. 2 | 3 | VectOffset=512 4 | 5 | MultiSegAddr=0 6 | -------------------------------------------------------------------------------- /Libs/NUCLEO-WL55JC/stm32-secure-patching-bootloader_NUCLEO-WL55JC_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Libs/NUCLEO-WL55JC/stm32-secure-patching-bootloader_NUCLEO-WL55JC_v1.4.0.bin -------------------------------------------------------------------------------- /Libs/NUCLEO-WL55JC/stm32-secure-patching-bootloader_NUCLEO-WL55JC_v1.4.0.bin.asc: -------------------------------------------------------------------------------- 1 | a7b01dd1c4f0662e1dca1ded919fbb88cdbeb0d6b8efe8fb98cb05f0c4765d66 stm32-secure-patching-bootloader_NUCLEO-WL55JC_v1.4.0.bin 2 | -------------------------------------------------------------------------------- /Libs/README.md: -------------------------------------------------------------------------------- 1 | ## STM32 Secure Patching Bootloader 2 | 3 | ## Libraries 4 | 5 | In the `Libs` directory you will find the two key files needed by your application and build system to implement a secure bootloader and patching firmware update system: 6 | 7 | 1. `stm32-secure-patching-bootloader__.bin` : pre-built binary ready to run on the specified board. 8 | 2. `stm32-secure-patching-bootloader-linker-gcc__.ld` : application linker script configuration definitions. 9 | 10 | The capabilities built into the stm32-secure-patching-bootloader are dependent on the board it is targeting. For example, on boards that support USB host, the ability to update from USB flash drives may have been integrated and enabled. 11 | On boards that offer external flash, the multi-segment feature may have been enabled to allow placement of a portion of SLOT0 and all of SLOT1 in external flash. 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Linker/README.md: -------------------------------------------------------------------------------- 1 | ## STM32 Secure Patching Bootloader 2 | 3 | ## Common Linker Script 4 | 5 | Most applications and most targets can use the same linker script, provided that 6 | certain target-specific preamble configuration is available. 7 | 8 | This premable typically looks like this. The target-specific vector table offset and 9 | RAM size is incorporated into the constants. 10 | 11 | 12 | ``` 13 | /* Entry Point */ 14 | ENTRY(Reset_Handler) 15 | 16 | /* Highest address of the user mode stack */ 17 | _estack = 0x20005000; /* end of RAM specific to the device. */ 18 | 19 | /* Generate a link error if heap and stack don't fit into RAM 20 | * These do not reserve memory for these areas but rather just 21 | * ensure this amount is 'free' after everything else is placed. 22 | */ 23 | _Min_Heap_Size = 0x200; /* required amount of heap */ 24 | _Min_Stack_Size = 0x400; /* required amount of stack */ 25 | 26 | INCLUDE stm32-secure-patching-bootloader-linker-gcc__.ld 27 | 28 | /* Specific ROM/RAM UserApp definition */ 29 | APPLI_region_intvec_start__ = STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START + 0x200; /* Cortex-M7: 0x400, others: 0x200 */ 30 | APPLI_region_ROM_start = STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_START + VECTOR_SIZE + 0x200; /* Cortex-M7: 0x400, others: 0x200 */ 31 | APPLI_region_ROM_length = STM32_SECURE_PATCHING_BOOTLOADER_SLOT0_END - APPLI_region_ROM_start + 1; 32 | APPLI_region_RAM_start = STM32_SECURE_PATCHING_BOOTLOADER_RAM_START; 33 | APPLI_region_RAM_length = _estack - APPLI_region_RAM_start; 34 | 35 | /* Specify the memory areas */ 36 | MEMORY 37 | { 38 | ISR_VECTOR (rx) : ORIGIN = APPLI_region_intvec_start__, LENGTH = VECTOR_SIZE 39 | APPLI_region_ROM : ORIGIN = APPLI_region_ROM_start, LENGTH = APPLI_region_ROM_length 40 | APPLI_region_RAM : ORIGIN = APPLI_region_RAM_start, LENGTH = APPLI_region_RAM_length 41 | } 42 | 43 | /* Include the SECTIONS (not target-specific) */ 44 | INCLUDE stm32-secure-patching-bootloader-app-linker-sections_.ld 45 | 46 | ``` 47 | 48 | For *Multisegment and/or external (O)(Q)SPI flash targets* add a QSPI memory region and use the multiseg linker script: 49 | 50 | ``` 51 | MEMORY 52 | { 53 | ISR_VECTOR (rx) : ORIGIN = APPLI_region_intvec_start__, LENGTH = VECTOR_SIZE 54 | APPLI_region_ROM : ORIGIN = APPLI_region_ROM_start, LENGTH = APPLI_region_ROM_length 55 | APPLI_region_RAM : ORIGIN = APPLI_region_RAM_start, LENGTH = APPLI_region_RAM_length 56 | QSPI (rx) : ORIGIN = APPLI_region_MULTISEG_start__, LENGTH = 64M 57 | } 58 | 59 | /* Include the SECTIONS (not target-specific) for multi-segment flash slot allocation */ 60 | INCLUDE stm32-secure-patching-bootloader-app-linker-sections-multiseg_.ld 61 | 62 | ``` 63 | -------------------------------------------------------------------------------- /Linker/stm32-secure-patching-bootloader-app-linker-sections-multiseg_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | /* This is a linker script for the SECTIONS group that is suitable 2 | * for most applications on most most targets using multisement and/or (O)(Q)SPI 3 | * external flash. 4 | * 5 | * This requires target/application-specific preamble in the project's 6 | * linker script as outlined in the README.md. 7 | * 8 | * To use, add the following where the SECTIONS tag would normally go: 9 | * 10 | * INCLUDE sbsfu_app_linker_sections_multiseg.ld 11 | * 12 | */ 13 | 14 | 15 | /* Define output sections */ 16 | SECTIONS 17 | { 18 | /* The startup code goes first into FLASH */ 19 | .isr_vector : 20 | { 21 | . = ALIGN(8); 22 | KEEP(*(.isr_vector)) /* Startup code */ 23 | FILL(0); 24 | . = ORIGIN(ISR_VECTOR) + LENGTH(ISR_VECTOR) - 1; 25 | BYTE(0) 26 | . = ALIGN(8); 27 | } >ISR_VECTOR 28 | 29 | /* The program code and other data goes into FLASH */ 30 | .text : 31 | { 32 | . = ALIGN(8); 33 | *(.text) /* .text sections (code) */ 34 | *(.text*) /* .text* sections (code) */ 35 | *(.glue_7) /* glue arm to thumb code */ 36 | *(.glue_7t) /* glue thumb to arm code */ 37 | *(.eh_frame) 38 | 39 | KEEP (*(.init)) 40 | KEEP (*(.fini)) 41 | 42 | . = ALIGN(8); 43 | _etext = .; /* define a global symbol at end of code */ 44 | } >APPLI_region_ROM 45 | 46 | /* Constant data goes into FLASH */ 47 | .rodata : 48 | { 49 | . = ALIGN(8); 50 | *(.rodata) /* .rodata sections (constants, strings, etc.) */ 51 | *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ 52 | . = ALIGN(8); 53 | } >APPLI_region_ROM 54 | 55 | .ARM.extab : 56 | { 57 | . = ALIGN(8); 58 | *(.ARM.extab* .gnu.linkonce.armextab.*) 59 | . = ALIGN(8); 60 | } >APPLI_region_ROM 61 | .ARM : { 62 | . = ALIGN(8); 63 | __exidx_start = .; 64 | *(.ARM.exidx*) 65 | __exidx_end = .; 66 | . = ALIGN(8); 67 | } >APPLI_region_ROM 68 | 69 | .preinit_array : 70 | { 71 | . = ALIGN(8); 72 | PROVIDE_HIDDEN (__preinit_array_start = .); 73 | KEEP (*(.preinit_array*)) 74 | PROVIDE_HIDDEN (__preinit_array_end = .); 75 | . = ALIGN(8); 76 | } >APPLI_region_ROM 77 | 78 | .init_array : 79 | { 80 | . = ALIGN(8); 81 | PROVIDE_HIDDEN (__init_array_start = .); 82 | KEEP (*(SORT(.init_array.*))) 83 | KEEP (*(.init_array*)) 84 | PROVIDE_HIDDEN (__init_array_end = .); 85 | . = ALIGN(8); 86 | } >APPLI_region_ROM 87 | .fini_array : 88 | { 89 | . = ALIGN(8); 90 | PROVIDE_HIDDEN (__fini_array_start = .); 91 | KEEP (*(SORT(.fini_array.*))) 92 | KEEP (*(.fini_array*)) 93 | PROVIDE_HIDDEN (__fini_array_end = .); 94 | . = ALIGN(8); 95 | } >APPLI_region_ROM 96 | 97 | /* Section used to store fault information across reboots 98 | */ 99 | .faultinfo (NOLOAD): 100 | { 101 | . = ALIGN(4); 102 | _start_of_faultinfo = .; 103 | *(.faultinfo) 104 | *(.faultinfo.*) 105 | . = . + 1; 106 | . = ALIGN(64); 107 | _end_of_faultinfo = .; 108 | } >APPLI_region_RAM 109 | 110 | /* used by the startup to initialize data */ 111 | _sidata = LOADADDR(.data); 112 | 113 | /* Initialized data sections goes into RAM, load LMA copy after code */ 114 | .data : 115 | { 116 | . = ALIGN(8); 117 | _sdata = .; /* create a global symbol at data start */ 118 | *(.ramfunc*) /* Functions setup to run in RAM */ 119 | *(.data) /* .data sections */ 120 | *(.data*) /* .data* sections */ 121 | 122 | . = ALIGN(8); 123 | _edata = .; /* define a global symbol at data end */ 124 | } >APPLI_region_RAM AT>APPLI_region_ROM 125 | 126 | /* Extra ROM section (last one) to make sure the binary size is a multiple of the AES block size (16 bytes) */ 127 | .align16 : 128 | { 129 | . = . + 1; /* _edata=. is aligned on 8 bytes so could be aligned on 16 bytes: add 1 byte gap */ 130 | . = ALIGN(16) - 1; /* increment the location counter until next 16 bytes aligned address (-1 byte) */ 131 | BYTE(0); /* allocate 1 byte (value is 0) to be a multiple of 16 bytes */ 132 | } > APPLI_region_ROM 133 | 134 | /* Uninitialized data section */ 135 | . = ALIGN(4); 136 | .bss : 137 | { 138 | /* This is used by the startup in order to initialize the .bss secion */ 139 | _sbss = .; /* define a global symbol at bss start */ 140 | __bss_start__ = _sbss; 141 | *(.bss) 142 | *(.bss*) 143 | *(COMMON) 144 | . = ALIGN(4); 145 | /* insert bss guard word at the end of the section */ 146 | __bss_guard = .; 147 | . = . + 4; 148 | /* end bss guard word */ 149 | _ebss = .; /* define a global symbol at bss end */ 150 | __bss_end__ = _ebss; 151 | } >APPLI_region_RAM 152 | 153 | /* User_heap_stack section, used to check that there is enough RAM left */ 154 | ._user_heap_stack : 155 | { 156 | . = ALIGN(8); 157 | PROVIDE ( end = . ); 158 | PROVIDE ( _end = . ); 159 | . = . + _Min_Heap_Size; 160 | . = . + _Min_Stack_Size; 161 | . = ALIGN(8); 162 | } >APPLI_region_RAM 163 | 164 | 165 | 166 | /* Remove information from the standard libraries */ 167 | /DISCARD/ : 168 | { 169 | libc.a ( * ) 170 | libm.a ( * ) 171 | libgcc.a ( * ) 172 | } 173 | 174 | .ARM.attributes 0 : { *(.ARM.attributes) } 175 | 176 | /* Section for placement of resources into QSPI segment 177 | * This is not contiguous with the "ROM" segment, but must also be aligned 178 | * to 16 bytes for AES requirement. 179 | */ 180 | ExtFlashSection : 181 | { 182 | *(ExtFlashSection) 183 | 184 | . = . + 1; /* _edata=. is aligned on 8 bytes so could be aligned on 16 bytes: add 1 byte gap */ 185 | . = ALIGN(16) - 1; /* increment the location counter until next 16 bytes aligned address (-1 byte) */ 186 | BYTE(0); /* allocate 1 byte (value is 0) to be a multiple of 16 bytes */ 187 | } >QSPI 188 | 189 | } 190 | 191 | 192 | -------------------------------------------------------------------------------- /Linker/stm32-secure-patching-bootloader-app-linker-sections_v1.4.0.ld: -------------------------------------------------------------------------------- 1 | /* This is a linker script for the SECTIONS group that is suitable 2 | * for most applications on most most targets not using QSPI or 3 | * multisegment. 4 | * 5 | * This requires target/application-specific preamble in the project's 6 | * linker script as outlined in the README.md. 7 | * 8 | * To use, add the following where the SECTIONS tag would normally go: 9 | * 10 | * INCLUDE sbsfu_app_linker_sections.ld 11 | * 12 | */ 13 | 14 | 15 | /* Define output sections */ 16 | SECTIONS 17 | { 18 | /* The startup code goes first into FLASH */ 19 | .isr_vector : 20 | { 21 | . = ALIGN(8); 22 | KEEP(*(.isr_vector)) /* Startup code */ 23 | FILL(0); 24 | . = ORIGIN(ISR_VECTOR) + LENGTH(ISR_VECTOR) - 1; 25 | BYTE(0) 26 | . = ALIGN(8); 27 | } >ISR_VECTOR 28 | 29 | /* The program code and other data goes into FLASH */ 30 | .text : 31 | { 32 | . = ALIGN(8); 33 | *(.text) /* .text sections (code) */ 34 | *(.text*) /* .text* sections (code) */ 35 | *(.glue_7) /* glue arm to thumb code */ 36 | *(.glue_7t) /* glue thumb to arm code */ 37 | *(.eh_frame) 38 | 39 | KEEP (*(.init)) 40 | KEEP (*(.fini)) 41 | 42 | . = ALIGN(8); 43 | _etext = .; /* define a global symbol at end of code */ 44 | } >APPLI_region_ROM 45 | 46 | /* Constant data goes into FLASH */ 47 | .rodata : 48 | { 49 | . = ALIGN(8); 50 | *(.rodata) /* .rodata sections (constants, strings, etc.) */ 51 | *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ 52 | . = ALIGN(8); 53 | } >APPLI_region_ROM 54 | 55 | .ARM.extab : 56 | { 57 | . = ALIGN(8); 58 | *(.ARM.extab* .gnu.linkonce.armextab.*) 59 | . = ALIGN(8); 60 | } >APPLI_region_ROM 61 | .ARM : { 62 | . = ALIGN(8); 63 | __exidx_start = .; 64 | *(.ARM.exidx*) 65 | __exidx_end = .; 66 | . = ALIGN(8); 67 | } >APPLI_region_ROM 68 | 69 | .preinit_array : 70 | { 71 | . = ALIGN(8); 72 | PROVIDE_HIDDEN (__preinit_array_start = .); 73 | KEEP (*(.preinit_array*)) 74 | PROVIDE_HIDDEN (__preinit_array_end = .); 75 | . = ALIGN(8); 76 | } >APPLI_region_ROM 77 | 78 | .init_array : 79 | { 80 | . = ALIGN(8); 81 | PROVIDE_HIDDEN (__init_array_start = .); 82 | KEEP (*(SORT(.init_array.*))) 83 | KEEP (*(.init_array*)) 84 | PROVIDE_HIDDEN (__init_array_end = .); 85 | . = ALIGN(8); 86 | } >APPLI_region_ROM 87 | .fini_array : 88 | { 89 | . = ALIGN(8); 90 | PROVIDE_HIDDEN (__fini_array_start = .); 91 | KEEP (*(SORT(.fini_array.*))) 92 | KEEP (*(.fini_array*)) 93 | PROVIDE_HIDDEN (__fini_array_end = .); 94 | . = ALIGN(8); 95 | } >APPLI_region_ROM 96 | 97 | /* Section used to store fault information across reboots 98 | */ 99 | .faultinfo (NOLOAD): 100 | { 101 | . = ALIGN(4); 102 | _start_of_faultinfo = .; 103 | *(.faultinfo) 104 | *(.faultinfo.*) 105 | . = . + 1; 106 | . = ALIGN(64); 107 | _end_of_faultinfo = .; 108 | } >APPLI_region_RAM 109 | 110 | /* used by the startup to initialize data */ 111 | _sidata = LOADADDR(.data); 112 | 113 | /* Initialized data sections goes into RAM, load LMA copy after code */ 114 | .data : 115 | { 116 | . = ALIGN(8); 117 | _sdata = .; /* create a global symbol at data start */ 118 | *(.ramfunc*) /* Functions setup to run in RAM */ 119 | *(.data) /* .data sections */ 120 | *(.data*) /* .data* sections */ 121 | 122 | . = ALIGN(8); 123 | _edata = .; /* define a global symbol at data end */ 124 | } >APPLI_region_RAM AT>APPLI_region_ROM 125 | 126 | /* Extra ROM section (last one) to make sure the binary size is a multiple of the AES block size (16 bytes) */ 127 | .align16 : 128 | { 129 | . = . + 1; /* _edata=. is aligned on 8 bytes so could be aligned on 16 bytes: add 1 byte gap */ 130 | . = ALIGN(16) - 1; /* increment the location counter until next 16 bytes aligned address (-1 byte) */ 131 | BYTE(0); /* allocate 1 byte (value is 0) to be a multiple of 16 bytes */ 132 | } > APPLI_region_ROM 133 | 134 | /* Uninitialized data section */ 135 | . = ALIGN(4); 136 | .bss : 137 | { 138 | /* This is used by the startup in order to initialize the .bss secion */ 139 | _sbss = .; /* define a global symbol at bss start */ 140 | __bss_start__ = _sbss; 141 | *(.bss) 142 | *(.bss*) 143 | *(COMMON) 144 | . = ALIGN(4); 145 | /* insert bss guard word at the end of the section */ 146 | __bss_guard = .; 147 | . = . + 4; 148 | /* end bss guard word */ 149 | _ebss = .; /* define a global symbol at bss end */ 150 | __bss_end__ = _ebss; 151 | } >APPLI_region_RAM 152 | 153 | /* User_heap_stack section, used to check that there is enough RAM left */ 154 | ._user_heap_stack : 155 | { 156 | . = ALIGN(8); 157 | PROVIDE ( end = . ); 158 | PROVIDE ( _end = . ); 159 | . = . + _Min_Heap_Size; 160 | . = . + _Min_Stack_Size; 161 | . = ALIGN(8); 162 | } >APPLI_region_RAM 163 | 164 | 165 | 166 | /* Remove information from the standard libraries */ 167 | /DISCARD/ : 168 | { 169 | libc.a ( * ) 170 | libm.a ( * ) 171 | libgcc.a ( * ) 172 | } 173 | 174 | .ARM.attributes 0 : { *(.ARM.attributes) } 175 | } 176 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## STM32 Secure Patching Bootloader 2 | 3 | A Secure Patching Bootloader and Firmware Update System for all **STM32** MCUs. 4 | 5 | The only bootloader and firmware update system you may ever need. Works with almost any STM32 MCU family using the [STM32CubeIDE](https://www.st.com/en/development-tools/stm32cubeide.html) development environment. 6 | 7 | This unique solution is an easy way to get a secure and robust bootloader that offers multiple firmware update methods built-in, including delta patching. It is a **plug'n'play** system that requires no configuration and just works! 8 | 9 | **Features:** 10 | 11 | * Robust: dual slot (SLOT0 - active and SLOT1 - download) firmware updating. 12 | * Secure: signed (ECDSA) and encrypted (AES) firmware update images (.sfb) and delta patches (.sfbp) 13 | * Optional support for download slot (SLOT1) in external flash. 14 | * Optional support for distributing active slot (SLOT0) firmware image over internal *and* external flash - known as *MultiSegment* capability - benefiting large applications like TouchGFx GUI systems that include assets that must be located in external flash. 15 | * Firmware delta patching engine built-in and is accessible by both the bootloader and the application at runtime for powerful OTA delta updates over any update mode (cell, lorawan, ethernet, bluetooth, UART, what have you). 16 | * Multiple secure firmware update methods from bootloader: YMODEM over UART, USB flash drive (where available). 17 | * Optional automatic 'git' semantic versioning support: automatically version your application firmware end-to-end with git repository tags. 18 | * Useful progress messages printed to UART. 19 | * Can deploy and update TouchGFX applications. 20 | 21 | This secure patching bootloader and firmware update system is licensed according to STMicroelectronics' Ultimate Liberty Software License Agreement (see [LICENSE](LICENSE.md)) and free to use on any NUCLEO, DISCO or EVAL board we support here. If your NUCLEO, DISCO or EVAL board is missing, post an issue and we'll add it. 22 | 23 | The stm32-secure-patching-bootloader reserves between **40 - 80 KB** at the beginning of internal flash, depending on MCU and feature selected (support for USB flash loader, external flash / multisegment add to size). 24 | The bootloader also reserves about **5 KB** at the start of SRAM for the secure patching engine's stack and state, fully indepdenent of the application. This allows the application to perform in-application firmware updates and make other runtime requests of the bootloader (get firmware version, etc). 25 | 26 | Check out the **FAQ** [here](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/wiki#faq) in the wiki. 27 | 28 | ### Quick Start Guide 29 | 30 | Refer to details in [Product Documentation](Docs/README.md). 31 | 32 | ### Supported Boards 33 | 34 | This list will grow over time as we work to support key STM32 NUCLEO, DISCO, EVAL and 3rd-party boards. Note that we group -DISCO, -Discovery and -DK as just `DISCO`. 35 | 36 | | Family | Boards | Board Config | Reference Projects | 37 | | --- | --- | --- | --- | 38 | | STM32G0 | [NUCLEO-G0B1RE](https://www.st.com/en/evaluation-tools/nucleo-g0b1re.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/NUCLEO-G0B1RE/stm32-secure-patching-bootloader-README_NUCLEO-G0B1RE_v1.4.0.txt) | 39 | | STM32L0 | [NUCLEO-L073RZ](https://www.st.com/en/evaluation-tools/nucleo-l073rz.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/NUCLEO-L073RZ/stm32-secure-patching-bootloader-README_NUCLEO-L073RZ_v1.4.0.txt) | 40 | | | [B-L072Z-LRWAN1](https://www.st.com/en/evaluation-tools/b-l072z-lrwan1.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/B-L072Z-LRWAN1/stm32-secure-patching-bootloader-README_B-L072Z-LRWAN1_v1.4.0.txt) | 41 | | STM32L4 | [NUCLEO-L412KB](https://www.st.com/en/evaluation-tools/nucleo-l412kb.html) |[README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/NUCLEO-L412KB/stm32-secure-patching-bootloader-README_NUCLEO-L412KB_v1.4.0.txt) | 42 | | | [NUCLEO-L452RE](https://www.st.com/en/evaluation-tools/nucleo-l452re.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/NUCLEO-L452RE/stm32-secure-patching-bootloader-README_NUCLEO-L452RE_v1.4.0.txt) | 43 | | | [NUCLEO-L476RG](https://www.st.com/en/evaluation-tools/nucleo-l476rg.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/NUCLEO-L476RG/stm32-secure-patching-bootloader-README_NUCLEO-L476RG_v1.4.0.txt) | 44 | | | [NUCLEO-L496ZG](https://www.st.com/en/evaluation-tools/nucleo-l496zg.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/NUCLEO-L496ZG/stm32-secure-patching-bootloader-README_NUCLEO-L496ZG_v1.4.0.txt) | 45 | | | [DISCO-L476G](https://www.st.com/en/evaluation-tools/32l476gdiscovery.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/DISCO-L476G/stm32-secure-patching-bootloader-README_DISCO-L476G_v1.4.0.txt) | 46 | | | [DISCO-L496G](https://www.st.com/en/evaluation-tools/32l496gdiscovery.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/DISCO-L496G/stm32-secure-patching-bootloader-README_DISCO-L496G_v1.4.0.txt) | 47 | | STM32L4+ | [DISCO-L4R9I](https://www.st.com/en/evaluation-tools/32l4r9idiscovery.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/DISCO-L4R9I/stm32-secure-patching-bootloader-README_DISCO-L4R9I_v1.4.0.txt) | [FreeRTOS_LowPower IAP](https://github.com/firmwaremodules/STM32CubeL4/tree/master/Projects/32L4R9IDISCOVERY/Applications/FreeRTOS/FreeRTOS_LowPower) | 48 | | | [B-L4S5I-IOT01A](https://www.st.com/en/evaluation-tools/b-l4s5i-iot01a.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/B-L4S5I-IOT01A/stm32-secure-patching-bootloader-README_B-L4S5I-IOT01A_v1.4.0.txt) | 49 | | STM32L5 | [DISCO-L562E](https://www.st.com/en/evaluation-tools/stm32l562e-dk.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/DISCO-L562E/stm32-secure-patching-bootloader-README_DISCO-L562E_v1.4.0.txt) | 50 | | STM32WL | [NUCLEO-WL55JC](https://www.st.com/en/evaluation-tools/nucleo-wl55jc.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/NUCLEO-WL55JC/stm32-secure-patching-bootloader-README_NUCLEO-WL55JC_v1.4.0.txt) | 51 | | | [LORA-E5-DEV](https://www.seeedstudio.com/LoRa-E5-Dev-Kit-p-4868.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/LORA-E5-DEV/stm32-secure-patching-bootloader-README_LORA-E5-DEV_v1.4.0.txt) | 52 | | | [LORA-E5-MINI](https://www.seeedstudio.com/LoRa-E5-mini-STM32WLE5JC-p-4869) (use DEV libs) | 53 | | STM32F4 | [NUCLEO-F429ZI](https://www.st.com/en/evaluation-tools/nucleo-f429zi.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/NUCLEO-F429ZI/stm32-secure-patching-bootloader-README_NUCLEO-F429ZI_v1.4.0.txt) | [Web Server IAP Update](https://github.com/firmwaremodules/STM32CubeF4/tree/master/Projects/STM32F429ZI-Nucleo/Applications/LwIP/LwIP_HTTP_Server_Netconn_RTOS) 54 | | | [DISCO-F469I](https://www.st.com/en/evaluation-tools/32f469idiscovery.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/DISCO-F469I/stm32-secure-patching-bootloader-README_DISCO-F469I_v1.4.0.txt) | [TouchGFX Demo](https://github.com/firmwaremodules/STM32CubeF4/tree/master/Projects/STM32469I-Discovery/Demonstrations/TouchGFX) 55 | | STM32F7 | [DISCO-F769I](https://www.st.com/en/evaluation-tools/32f769idiscovery.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/DISCO-F769I/stm32-secure-patching-bootloader-README_DISCO-F769I_v1.4.0.txt) | 56 | | STM32H7 | [DISCO-H745I](https://www.st.com/en/evaluation-tools/stm32h745i-disco.html) | [README](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/DISCO-H745I/stm32-secure-patching-bootloader-README_DISCO-H745I_v1.4.0.txt) | 57 | 58 | 59 | Please post an issue if you'd like a particular board supported. 60 | 61 | ### IAP Reference Designs 62 | 63 | **List of IAP (In-Application Programming) firmware update open source reference designs using the stm32-secure-patching-bootloder.** 64 | 65 | These reference designs can be adapted to any board that the stm32-secure-patching-bootloader supports. Of course, the bootloader itself always has capability for secure YMODEM/UART and/or USB flash drive firmware update even if the application has failed or become unavailable. 66 | 67 | | Reference Project | Reference Board | Technique | 68 | | --- | --- | --- | 69 | | [FreeRTOS_LowPower IAP](https://github.com/firmwaremodules/STM32CubeL4/tree/master/Projects/32L4R9IDISCOVERY/Applications/FreeRTOS/FreeRTOS_LowPower) | [DISCO-L4R9I](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/DISCO-L4R9I/stm32-secure-patching-bootloader-README_DISCO-L4R9I_v1.4.0.txt) | YMODEM/UART interrupt mode | 70 | | [Web Server IAP Update](https://github.com/firmwaremodules/STM32CubeF4/tree/master/Projects/STM32F429ZI-Nucleo/Applications/LwIP/LwIP_HTTP_Server_Netconn_RTOS) | [NUCLEO-F429ZI](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/NUCLEO-F429ZI/stm32-secure-patching-bootloader-README_NUCLEO-F429ZI_v1.4.0.txt) | Ethernet / TCPIP/ multipart forms file upload | 71 | | [TouchGFX Demo](https://github.com/firmwaremodules/STM32CubeF4/tree/master/Projects/STM32469I-Discovery/Demonstrations/TouchGFX) | [DISCO-F469I](https://github.com/firmwaremodules/stm32-secure-patching-bootloader/tree/main/Libs/DISCO-F469I/stm32-secure-patching-bootloader-README_DISCO-F469I_v1.4.0.txt) | Bootloader integration with a real TouchGFX app 72 | 73 | 74 | 75 | ### Delta Patch Engine 76 | 77 | The Delta Patch Engine is built into the bootloader and ready to be accessed by your application at runtime or by the bootloader through UART or USB flash drive updates. The Delta Patch Engine features: 78 | 79 | * Same security as regular full-image .sfb files. The .sfbp patch container is secured with the same digital signature and encryption technology. 80 | * Regenerates the full firmware update image into SLOT1 from the content of the patch and the content of the existing application in SLOT0. The final result is as-if a full image .sfb update was performed (in fact exactly the same as the SHA256 digest will attest). 81 | * Performs SHA256 digest check on the source image (SLOT0) and compares to expected digest embedded in the patch container before taking any action. 82 | * Single-byte streaming update capability. The patch engine can be fed any number of bytes at a time (including just 1 byte) to support any IAP / OTA update method. 83 | * The installation of firmware (copy from SLOT1 to SLOT0) is always handled by the bootloader at startup and only occurs after the regenerated firmware image in SLOT1 has been verified and authenticated and the user application has requested or initiated a reboot. 84 | * The patching engine API consists of just two core functions (`SE_PATCH_Init`, `SE_PATCH_Data`) described in one header file and bound at link time through a linker include script. 85 | 86 | 87 | ### TouchGFX 88 | Yes! With the STM32 Secure Patching Bootloader you can deploy and update your TouchGFX application with assets on external flash as easily as any other. We call this capability **MultiSegment**. 89 | 90 | The MultiSegment feature solves the problem of how to update monolithic applications that are larger than the device's internal flash, or equivalently, applications that that are linked to be executed in two disjoint flash regions - for example internal and external flash. 91 | 92 | This problem is common with GUI systems where you might find a 300 KB firmware application coupled with 4 MB of GUI assets like images and videos and fonts etc. In advanced GUI systems like TouchGFx, these assets are accessed through regular MCU memory read instructions and must therefore be available in a program-readable memory region. 93 | Since internal flash (at 0x0800 0000) is not large enough to hold all of these assets, a memory region dedicated to an external flash through the Q/OSPI peripheral on STM32 devices is used. This region is typically assigned to 0x9000 0000. 94 | 95 | The application's linker script contains a section definition located at 0x9000 0000 to which all GUI assets are placed at link time. The resultant .hex file remains compact because it contains just the data along with addresses to be written. 96 | Loading this .hex file with an external-flash-aware programmer like STM32CubeProgrammer works fine, but you do not have a bootloader nor capability to update your application and GUI assets in the field. 97 | 98 | The stm32-secure-patching-bootloader with the MultiSegment feature abstracts away this low-level complexity from the bootloader and firmware update engines. From their point of view, SLOT0 is a contiguous memory region of arbitrary size - it can be much larger than internal flash (i.e. 16 MB) - and will hold the entire application image including GUI assets. 99 | 100 | So what does MultiSegment mean to you? It means you can build and deploy your 4 or 8 or 16 or 24 MB GUI application as easily and seamlessly as if it was a regular small 300 KB application that fits entirely and neatly in your MCUs internal flash. Furthermore, the delta patching feature built into the stm32-secure-patching-bootloader 101 | offers a huge benefit for large applications. Imagine changing only functionality or fixing a bug in your 16 MB combined application. With delta patching, only the difference - the .sfbp patch file - needs to be distributed to your customers and/or devices in the field, potentially a few hundred to few thousand bytes. If you had to distribute this over a wireless link think of the savings in bandwidth and cost and time you would realize! 102 | The stm32-secure-patching-bootloader's USB flash drive update feature is also a great way to update devices in the field with patches or full images - after all, GUI devices are built for human interaction and often don't necessarily have wireless links but may have an exposed USB port. 103 | 104 | See this [MultiSegment Graphic](Docs/stm32-secure-patching-bootloader-MultiSegment_rev1_Dec2021.pdf) illustrating slot placement. 105 | 106 | _Since you've read this far:_ 107 | 108 | I will happily generate a made-to-order registered version of the stm32-secure-patching-bootloader to support commercial projects on custom hardware. 109 | Please head over to my [store](https://www.firmwaremodules.com/products/stm32-secure-patching-bootloader) to get pricing details. 110 | [Contact me](mailto:contact@firmwaremodules.com) to get the ball rolling. 111 | 112 | Commercial, registered users optionally get an additional **production** version of the bootloader binary that checks and enforces **RDP Level 2** 113 | to help mitigate chip-level attacks such as [RDP regression](https://www.usenix.org/system/files/conference/woot17/woot17-paper-obermaier.pdf). Your use of the production version is optional. When utilized, it will 114 | automatically set RDP Level 2 and write protect the bootloader flash area at startup. 115 | 116 | ### Release Notes 117 | 118 | **v1.4.0 - Mar 2023** 119 | 120 | * Add support for new platforms and boards: G0 (NUCLEO-G0B1RE) H7 (DISCO-H745I) WL (NUCLEO-WL55JC) F4 (DISCO-F469I) L4 (NUCLEO-L476RG) 121 | * Prints size of binaries detected in each slot in diagnostic output. 122 | * Bootloader disables cache before launching application on all boards that use cache (prevents faulting when application tries to re-enable already enabled cache in some cases). 123 | * Fixes YMODEM load button trigger wrong state for NULEO-L452RE. 124 | * Optimization: greatly speeds up patching updates (3x or more) on large binaries utilizing external flash. 125 | * Optimization: removes one redundant header verification in virgin device or two redundant header verifications in devices that have undergone at least one update cycle. Saves between 50 - 2000 ms per header verification of bootup time depending on MCU capability. 126 | * Ensures hardware CRC is powered up when needed during SE_PATCH_Data() API calls. 127 | * Adds make_keys_vXm.bat scripts to automatically generate machine.txt file (often overlooked otherwise). 128 | 129 | **v1.3.0 - Nov 2022** 130 | 131 | * Now works with applications built using STM32CubeIDE 1.9 and later including version 1.10.1. 132 | * Simplifies application integration process by removing the need to link with a library for access to SE_PATCH (in-application firmware update) APIs. Now, the SE_PATCH engine APIs are available to all applications by default. 133 | * Adds new platform support for STM32L4+ and DISCO-L4R9I and B-L4S5I-IOT01A boards. 134 | * Adds new platform support for STM32L5 and the DISCO-L562E board. 135 | 136 | **v1.2.0 - Aug 2022** 137 | 138 | * Adds support for four new STM32L4 family dev boards. 139 | * Adds runtime API to get bootloader version string from application. 140 | * Enables USB flash drive update on DISCO-L496G. 141 | * Updates API interface documentation in `stm32_secure_patching_bootloader_interface_v1.2.0.h` 142 | * Adds test binaries for each board under `Test/` directory. Allows for quick validation of bootloader board support and evaluation of the firmware update process. 143 | 144 | **v1.1.0 - May 2022** 145 | 146 | * Adds new platform support for STM32WLE5 and SeeedStudio LORA-E5-DEV and LORA-E5-MINI boards. 147 | * Adds specific support for the B-L072Z-LRWAN1 board. 148 | * Adds README to each library package to describe flash layout and bootloader configuration. 149 | * Changes postbuild command to allow user to specify location of bootloader Libs directory. 150 | * Removes vector offset and multiseg address parameters in the postbuild command script (these are now defined in the bootloader library package artifacts). 151 | 152 | **v1.0.0 - Dec 2021** 153 | 154 | * Initial Release 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /Scripts/README.md: -------------------------------------------------------------------------------- 1 | ## STM32 Secure Patching Bootloader 2 | 3 | ## Scripts 4 | 5 | 6 | * `postbuild.sh` is called by the application project as its postbuild step. Please see the file for argument usage and the [demoapp repository](https://github.com/firmwaremodules/stm32-secure-patching-bootloader-demoapp) for usage examples. 7 | * `make_keys_v6m.bat` or `make_keys_v7m.bat` creates random unique AES and ECDSA keys for use by postbuild.sh. They keys must be unique to each application using this system. Keys are typically placed in the application project's `Keys` directory. See [demoapp repository](https://github.com/firmwaremodules/stm32-secure-patching-bootloader-demoapp) for examples. 8 | 9 | Note: use `v6m` only for Cortex-M0+ targets like STM32L0, F0 or G0. For all other targets use `v7m` variant. 10 | 11 | ## Key Management 12 | 13 | The bootloader and secure firmware update security system consists of two private keys: 14 | 15 | * AES-CBC key (encryption - confidentiality) 16 | * ECSDA key (signing - authentication) 17 | 18 | The `prepareimage.py` tool is used for generating both keys. 19 | 20 | These keys must be unique to each project to prevent loading wrong firmware. 21 | 22 | **These keys are the means by which the stm32-secure-patching-bootloader accepts or rejects firmware for a given product**. 23 | 24 | Do not use the same keys for multiple projects/products or the stm32-secure-patching-bootloader in one product could 25 | update to firmware meant for another product. 26 | 27 | Use the 'make_keys_v7m.bat' convenience script located in `Scripts` to generate the keys 28 | automatically in the specified project `Keys` directory, or follow these manual steps: 29 | 30 | Open a console window to `Tools` and run these commands: 31 | 32 | 1. `python prepareimage.py keygen -k Cipher_Key_AES_CBC.bin -t aes-cbc` 33 | 2. `python prepareimage.py keygen -k Signing_PrivKey_ECC.txt -t ecdsa-p256` 34 | 5. Add and/or commit changes to these 2 files into the project's `Keys` directory. 35 | 36 | Also, in `Keys` directory, `machine.txt` must exist, and must contain either `V7M` for a non-Cortex-M0 target, 37 | or `V6M` for a Cortex-M0 target. Again, see the [demoapp repository](https://github.com/firmwaremodules/stm32-secure-patching-bootloader-demoapp) for examples on `Keys` directory setup. 38 | 39 | -------------------------------------------------------------------------------- /Scripts/STM32CubeIDE/postbuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash - 2 | 3 | # Copyright(c) 2018 STMicroelectronics International N.V. 4 | # Copyright 2017 Linaro Limited 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | # 20 | # Copyright (c) 2021-2022 Firmware Modules Inc. 21 | # 22 | # Permission is hereby granted, free of charge, to any person obtaining a copy 23 | # of this software and associated documentation files(the "Software"), to deal 24 | # in the Software without restriction, including without limitation the rights 25 | # to use, copy, modify, merge, publish, distribute, sublicense, and /or sell 26 | # copies of the Software, and to permit persons to whom the Software is 27 | # furnished to do so, subject to the following conditions : 28 | # 29 | # The above copyright notice and this permission notice shall be included in all 30 | # copies or substantial portions of the Software. 31 | # 32 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 33 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 34 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 35 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 36 | # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 37 | # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 38 | # OR OTHER DEALINGS IN THE SOFTWARE. 39 | # 40 | 41 | 42 | 43 | # Arguments: 44 | # 45 | # arg1 - Name of application input .elf file example: "${BuildArtifactFileBaseName}.elf" 46 | # arg2 - Keys directory relative to build directory. example: "../../Keys" 47 | # arg3 - Binary directory relative to build directory. example: "../../../../../Binary" 48 | # arg4 - Libs directory relative to the build directory. example: "../../../../../../../Bootloader/Libs" 49 | # arg5 - Build version (0 or 0.0.0 for auto version) 50 | # arg6 - Patch reference version (if not found, no patch generated) 51 | # arg7 - Board name (e.g. NUCLEO-L073RZ) 52 | # arg8 - Bootloader version (e.g. 1.0.0) 53 | 54 | # If you are following the project structure outlined in the demonstration application: 55 | # 56 | # Postbuild command is "../../../../../../../Bootloader/Scripts/STM32CubeIDE/postbuild.sh" "${BuildArtifactFileBaseName}" "../../Keys" "../../../../../Binary" "1.0.0" "1.0.0" "NUCLEO-L073RZ" "1.0.0" 57 | # Build Patch Board BootVer 58 | # 59 | # arg2 is "../../Keys" 60 | # arg3 is "../../../../../Binary" 61 | # arg4 is "../../../../../../../Bootloader/Libs" 62 | # 63 | # |- Project\ 64 | # | |- Binary\ 65 | # |- DemoApp\ 66 | # | - \ 67 | # | - STM32CubeIDE\ 68 | # |- _\ (STM32CubeIDE project folder .project .cproject) 69 | # | | - \ (e.g. Debug) 70 | # | - Keys\ 71 | # 72 | 73 | ApplicationName=$1 74 | BuildVer=$5 75 | PatchRefVer=$6 76 | BoardName=$7 77 | BootVer=$8 78 | 79 | # Setup references to the stm32-secure-patching-bootloader inputs 80 | # Path to *this* script is derived from the name. 81 | # This points to the Script dir 82 | ScriptDir=$(realpath $(dirname "$0")) 83 | # We need reference to the Tools dir 84 | ToolsDir=$(realpath $ScriptDir/../../Tools) 85 | 86 | # Setup references to the application project inputs and outputs 87 | BuildDir=`pwd` 88 | # We need reference to the project's Keys dir 89 | KeysDir=$(realpath $BuildDir/$2) 90 | # We need reference to the output products directory 91 | BinaryDir=$(realpath $BuildDir/$3) 92 | # We need reference to the Libs dir 93 | LibsDir=$(realpath $BuildDir/$4) 94 | 95 | ret=$? 96 | 97 | if [ $ret != 0 ]; then 98 | echo "Fatal error in postbuild arguments." 99 | exit 1 100 | fi 101 | 102 | OutputDump=$BuildDir/output.txt 103 | 104 | echo "Running postbuild" 105 | echo "Running postbuild" >> $OutputDump 106 | 107 | elf=${ApplicationName}.elf 108 | bin=${ApplicationName}.bin 109 | 110 | if [ ! -e $ToolsDir ]; then 111 | echo "FATAL: ToolsDir "$ToolsDir" is not found." 112 | exit 1 113 | fi 114 | if [ ! -e $LibsDir ]; then 115 | echo "FATAL: LibsDir "$LibsDir" is not found." 116 | exit 1 117 | fi 118 | if [ ! -e $KeysDir ]; then 119 | echo "FATAL: KeysDir "$KeysDir" is not found." 120 | exit 1 121 | fi 122 | if [ ! -e $BinaryDir ]; then 123 | echo "FATAL: BinaryDir "$BinaryDir" is not found." 124 | exit 1 125 | fi 126 | if [ -z ${BootVer+x} ]; then 127 | echo "FATAL: BootVer is not defined." 128 | exit 1 129 | fi 130 | if [ -z ${BoardName+x} ]; then 131 | echo "FATAL: BoardName is not defined." 132 | exit 1 133 | fi 134 | 135 | # Inclulde the board properties file: 136 | # VectOffset 137 | # MultiSegAddr 138 | Stm32BootBoardPostbuildName=${LibsDir}/${BoardName}/"stm32-secure-patching-bootloader-postbuild_"$BoardName"_"$BootVer".sh" 139 | source ${Stm32BootBoardPostbuildName} 140 | 141 | if [ $VectOffset == 0 ]; then 142 | echo "FATAL: VectOffset is not defined." 143 | exit 1 144 | fi 145 | 146 | echo Using: 147 | echo - $ScriptDir 148 | echo - $ToolsDir 149 | echo - $LibsDir 150 | echo - $BuildDir 151 | echo - $KeysDir 152 | echo - $BinaryDir 153 | echo - $OutputDump 154 | echo - $ApplicationName 155 | echo - $BuildVer 156 | echo - $PatchRefVer 157 | echo - $BoardName 158 | echo - $BootVer 159 | echo - $VectOffset 160 | echo - $MultiSegAddr 161 | 162 | #----------------------------------------------------------------------------------- 163 | 164 | # Versioning: 165 | # We are deriving the version automatically from the Git build environment. 166 | # We have to create a 3-digit major.minor.build version from this, so it 167 | # is paramount that the repository has a proper Git tag committed at some 168 | # time in the past. Without a proper tag, the version can only be parsed into 0.0.0. 169 | # The 3-digit build number is embedded into the firmware image 170 | # headers for the bootloader and patch engine to use to detect version mismatches, etc. 171 | # 172 | # This is how it works: 173 | # Version from Git is 'git describe --tags --always --dirty' and reports, for example: 174 | # v1.2.3-12-g1a2b3c4 175 | # This tag is "v1.2.3" and has 12 commits since. The 12 is added to the build number to 176 | # create the final 3-digit version: 1.2.15. In the case the build is from an immediate tag, 177 | # the tag simply becomes the 3-digit version. Released builds should always be built from an immediate tag. 178 | # 179 | # For patch generation, we need to know the "from version" on which to base the patch. 180 | # This is passed in as the 3-digit version that has been appended to a file that exists 181 | # in the Binary/PatchRef directory. For example, the IDE's postbuild command line 182 | # has "v1.1.2" as BuildVer. Then this script finds "PatchRef/DemoApp_v1.1.2.bin" to use as the 183 | # reference firmware. The new patch file would be "DemoApp_v1.1.2_v1.2.15.sfbp" and can only 184 | # be applied to devices that is currently running v1.1.2 firmware. Please note if you 185 | # tag "v1.2.3" use that as BuildVer, and if you tag "1.2.3" use that as arg 4. The parser 186 | # will find the 3-digit version from either format, and the file names always get the "BuildVer" string 187 | # whether that was set in the postbuild arguments or obtained from git. 188 | # 189 | # Lastly, please note that the 32-bit version field in the firmware image header can support 190 | # major: 0-255, minor: 0-65535 and build: 0-255. 191 | 192 | 193 | # 194 | # Inputs: 195 | # $1 - Output of 'git describe --tags --always --dirty' 196 | # 197 | # Returns: 198 | # VERSION_NUMBER : single 32-bit value representing the major.minor.patch extracted from the input. 199 | # VERSION_DIGITS : "major.minor.patch" extracted from the input. 200 | # 201 | # 0 on success, 1 on error. 202 | 203 | extract_version_number() { 204 | 205 | #echo "extract_version_number: $1" 206 | if [ -n "$1" ]; then 207 | # Confirm a 3-digit version number is present 208 | digitstring=`expr $1 : 'v*\([0-9]*\.[0-9]*\.[0-9]*\)'` 209 | #echo "string: $digitstring" 210 | 211 | if [ -n "$digitstring" ]; then 212 | # Find the components 213 | MAJOR=`expr $digitstring : '\([0-9]*\)\.[0-9]*\.[0-9]*'` 214 | MINOR=`expr $digitstring : '[0-9]*\.\([0-9]*\)\.[0-9]*'` 215 | PATCH=`expr $digitstring : '[0-9]*\.[0-9]*\.\([0-9]*\)'` 216 | # Check if there is a commit number component 217 | commitstring=`expr $1 : '.*-\([0-9]*\)-'` 218 | if [ -n "$commitstring" ]; then 219 | #echo "commit: $commitstring" 220 | PATCH=$((PATCH + $((commitstring)))) 221 | #echo $PATCH 222 | fi 223 | MAJOR=$((MAJOR & 0xFF)) 224 | MINOR=$((MINOR & 0xFFFF)) 225 | PATCH=$((PATCH & 0xFF)) 226 | VERSION_NUMBER=$(($((MAJOR << 24)) + $((MINOR << 8)) + $((PATCH)))) 227 | #echo "Version number=$VERSION_NUMBER" 228 | VERSION_DIGITS="$MAJOR.$MINOR.$PATCH" 229 | #echo "version digits=$VERSION_DIGITS" 230 | return 0 231 | 232 | fi 233 | fi 234 | 235 | # error 236 | VERSION_DIGITS="0.0.0" 237 | VERSION_NUMBER=0 238 | echo "Error finding version for input $1" >> $OutputDump 239 | return 1 240 | 241 | } 242 | 243 | # In auto-version mode, BuildVer is just "0" or "0.0.0" or "v0.0.0" and we use the output of 244 | # 'git describe --tags --always --dirty' 245 | # See if we are in auto mode and if so, get the version. 246 | # NOTE! if no tag exists with a parse-able vX.Y.Z or X.Y.Z semantic version scheme, 247 | # the generated firmware image header will have a version of 0.0.0 which is probably not what you want. 248 | # In other words, don't use auto-version mode unless you are explicitly tagging your release builds (git tag v1.0.0; git push --tags)' 249 | # It is OK to have intermediate builds after a tag: e.g. v1.0.0-12--g302ab62 will generate firmware header with version 1.0.0. 250 | extract_version_number $BuildVer 251 | if [ $VERSION_NUMBER == 0 ]; then 252 | echo "Auto version mode" 253 | BuildVer=`git describe --tags --always --dirty` 254 | fi 255 | 256 | echo "Using version=$BuildVer from $PatchRefVer" 257 | # Create new output.txt 258 | echo "Using version=$BuildVer from $PatchRefVer" > $OutputDump 259 | 260 | # Get the "to" version number 261 | extract_version_number $BuildVer 262 | version=$BuildVer 263 | version_number=$VERSION_NUMBER 264 | echo "version digits=$VERSION_DIGITS, number=$VERSION_NUMBER" >> $OutputDump 265 | 266 | # Get the "from" version number 267 | extract_version_number $PatchRefVer 268 | fromversion=$PatchRefVer 269 | fromversion_number=$VERSION_NUMBER 270 | echo "From version digits=$VERSION_DIGITS, number=$VERSION_NUMBER" >> $OutputDump 271 | 272 | # $version and $fromversion must include 'v' if required 273 | execname=${ApplicationName}_${version} 274 | patchrefname=${ApplicationName}_${fromversion} 275 | patchname=${ApplicationName}_${fromversion}_${version} 276 | 277 | #----------------------------------------------------------------------------------- 278 | 279 | 280 | PatchRefDir=$BinaryDir"/PatchRef" 281 | 282 | # Setup names of various outputs 283 | rawbin=$PatchRefDir"/"$execname".bin" 284 | patchrefbin=$PatchRefDir"/"$patchrefname".bin" 285 | patchbin=$PatchRefDir"/"$patchname".patch" 286 | sfu=$BinaryDir"/"$execname".sfu" 287 | sfup=$BinaryDir"/"$patchname".sfup" 288 | sfb=$BinaryDir"/"$execname".sfb" 289 | sfbp=$BinaryDir"/"$patchname".sfbp" 290 | sign=$BinaryDir"/"$execname".sign" 291 | signpatch=$BinaryDir"/"$patchname".sign" 292 | headerbin=$BinaryDir"/"$execname"sfuh.bin" 293 | bigbinary=$BinaryDir"/BOOT_"$execname".bin" 294 | bighex=$BinaryDir"/BOOT_"$execname".hex" 295 | segoff=$BinaryDir"/"$execname".segoff" 296 | 297 | iv=$KeysDir"/iv.bin" 298 | oemkey=$KeysDir"/Cipher_Key_AES_CBC.bin" 299 | ecckey=$KeysDir"/Signing_PrivKey_ECC.txt" 300 | # Machine type is specified by file on a per-project basis 301 | machine_type_file=$KeysDir"/machine.txt" 302 | # This bin file is written to this script directory for injection into the bootloader binary 303 | # user personalization section. 304 | keyfile=$KeysDir/boot_keys.bin 305 | 306 | # Get target machine type (v6m or v7m) - needed to know how to generate the key material. 307 | if [ -e "$machine_type_file" ]; then 308 | machine_type=`cat $machine_type_file` 309 | echo "machine type is "$machine_type 310 | echo "machine type is "$machine_type >> $OutputDump 311 | else 312 | echo "machine type file "$machine_type_file" is missing!" 313 | echo "machine type file "$machine_type_file" is missing!" >> $OutputDump 314 | fi 315 | 316 | # We must remove the IV file, if it exists, because we want a new, unique and random 317 | # encryption IV generated and placed into each signed header. If the IV file exists, it is used, 318 | # otherwise the image tool stores the one generated and used by the encryption algorithm. 319 | # It is essential that the IV is used only once for each encryption to maintain the 320 | # strength of the AES CBC algorithm. 321 | if [ -e "$iv" ]; then 322 | rm $iv 323 | fi 324 | 325 | # FW image processing tool 326 | prepareimage=$ToolsDir/prepareimage.py 327 | cmd=python 328 | 329 | echo "$cmd $prepareimage" >> $OutputDump 330 | # Make sure we have a Binary sub-folder for outputs 331 | if [ ! -e $BinaryDir ]; then 332 | mkdir $BinaryDir 333 | fi 334 | 335 | # Make sure we have a PatchRef sub-folder in Binary folder 336 | if [ ! -e $PatchRefDir ]; then 337 | mkdir $PatchRefDir 338 | fi 339 | 340 | # Set the patch difference tool 341 | patchtool=$ToolsDir"/jdiff.exe" 342 | 343 | # Setup reference to the stm32-secure-patching-bootloader binary we are going to use. 344 | Stm32BootBinName="stm32-secure-patching-bootloader_"$BoardName"_"$BootVer".bin" 345 | bootbin=$LibsDir/$BoardName/$Stm32BootBinName 346 | echo "Using "$Stm32BootBinName 347 | echo "Using "$bootbin >> $OutputDump 348 | 349 | # Ensure the assembled key file is not present before generating (it is opened for append) 350 | if [ -e "$keyfile" ]; then 351 | rm $keyfile 352 | fi 353 | # Generate the assembled key file 354 | command=$cmd" "$prepareimage" transbin -k "$oemkey" -v "$machine_type" "$keyfile 355 | $command >> $OutputDump 356 | ret=$? 357 | if [ $ret == 0 ]; then 358 | command=$cmd" "$prepareimage" transbin -k "$ecckey" -v "$machine_type" "$keyfile 359 | $command >> $OutputDump 360 | ret=$? 361 | fi 362 | if [ $ret != 0 ]; then 363 | msg="Error creating bootloader keys file: "$keyfile 364 | echo $msg 365 | exit 1 366 | fi 367 | 368 | # *********************************************************************************** 369 | # Preparation of the binary file is required before we can process it. 370 | # In the standard flow, the binary file is already produced by the toolchain. 371 | # However, to support multiple segments, the binary must be "compressed" to eliminate the filler 372 | # in the gaps between segments, especially if the segment is in completely different memory 373 | # region (e.g. QSPI 0x90000000). For both regular and multi-segment flows, we use our own 374 | # elf to binary file converter. This will overwrite anything the toolchain may have produced. 375 | # all we need is the ELF for any firmware production flow. 376 | command=$cmd" "$prepareimage" elf2segbin -e 1 -v 255 -s "$MultiSegAddr" -o "$segoff" "$elf" "$bin 377 | $command >> $OutputDump 378 | ret=$? 379 | if [ $ret != 0 ]; then 380 | msg="Error creating bin file from elf file." 381 | echo $msg 382 | exit 1 383 | fi 384 | 385 | # *********************************************************************************** 386 | # Create signed header and merged production image of new firmware. 387 | # Here we: 388 | # 1. Compute the unencrypted firmware binary hash (sha256), output %sign% 389 | # 2. Create the header using hash and firmware length, output %headerbin% 390 | # 3. Create the merged image, e.g. BOOT_DemoApp_BOARD_vX.Y.Z, output %bighex%, and %bigbinary% if segment offset is 0. 391 | # 392 | # The patch file uses the generated header in its processing steps. 393 | # *********************************************************************************** 394 | command=$cmd" "$prepareimage" enc -k "$oemkey" -i "$iv" "$bin" "$sfu 395 | $command >> $OutputDump 396 | ret=$? 397 | if [ $ret == 0 ]; then 398 | command=$cmd" "$prepareimage" sha256 "$bin" "$sign 399 | $command >> $OutputDump 400 | ret=$? 401 | if [ $ret == 0 ]; then 402 | command=$cmd" "$prepareimage" pack -k "$ecckey" -r 4 -v "$version_number" -i "$iv" -s "$segoff" -f "$sfu" -t "$sign" "$sfb" -o "$VectOffset 403 | $command >> $OutputDump 404 | echo Made $sfb 405 | ret=$? 406 | if [ $ret == 0 ]; then 407 | command=$cmd" "$prepareimage" header -k "$ecckey" -r 4 -v "$version_number" -i "$iv" -s "$segoff" -f "$sfu" -t "$sign" -o "$VectOffset" "$headerbin 408 | $command >> $OutputDump 409 | ret=$? 410 | if [ $ret == 0 ]; then 411 | # Create a combined hex file, which can handle multiple segments. This is the default format. 412 | command=$cmd" "$prepareimage" mergehex -v 255 -e 1 -i "$headerbin" -s "$bootbin" -b 0x08000000 -k "$keyfile" -o "$VectOffset" "$elf" "$bighex 413 | $command >> $OutputDump 414 | echo Made $bighex 415 | if [ $MultiSegAddr == 0 ]; then 416 | # If the segment offset is 0 (disabled) we can also create a combined binary. 417 | # Use the pre-built bootloader binary for this. All supported targets start flash at 0x08000000. 418 | command=$cmd" "$prepareimage" merge -v 0 -e 1 -i "$headerbin" -s "$bootbin" -b 0x08000000 -k "$keyfile" -o "$VectOffset" "$elf" "$bigbinary 419 | $command >> $OutputDump 420 | echo Made $bigbinary 421 | fi 422 | 423 | ret=$? 424 | 425 | # *********************************************************************************** 426 | # Create firmware update patch 427 | # 428 | # First, copy the generated raw application binary to the patch reference directory 429 | # to serve as a potential source for a future patch update. 430 | if [ $ret == 0 ]; then 431 | command="cp "$bin" "$rawbin 432 | $command >> $OutputDump 433 | ret=$? 434 | # If the selected "from" version exists and versions aren't equal perform patch generation 435 | if [ -e $patchrefbin ]; then 436 | if [ ! $version_number == $fromversion_number ]; then 437 | # Create the patch file between the specified reference version and this version 438 | command=$patchtool" "$patchrefbin" "$rawbin" "$patchbin 439 | $command >> $OutputDump 440 | # Error here can be set if there is no difference between files. 441 | ret=$? 442 | if [ $ret == 0 ]; then 443 | command=$cmd" "$prepareimage" enc -k "$oemkey" -i "$iv" -p 16 "$patchbin" "$sfup 444 | $command >> $OutputDump 445 | ret=$? 446 | if [ $ret == 0 ]; then 447 | command=$cmd" "$prepareimage" sha256 "$patchrefbin" "$signpatch 448 | $command >> $OutputDump 449 | ret=$? 450 | if [ $ret == 0 ]; then 451 | command=$cmd" "$prepareimage" packpatch -k "$ecckey" -r 4 -v "${fromversion_number}" -i "$iv" -f "$patchbin" --encpatch "$sfup" -t "$signpatch" --header "$headerbin" "$sfbp 452 | $command >> $OutputDump 453 | echo Made $sfbp 454 | ret=$? 455 | fi 456 | fi 457 | else 458 | echo "Error running patch difference tool: No differences detected." >> $OutputDump 459 | fi 460 | else 461 | echo "FROM version same as new version, skipping patch generation. ["$patchrefbin"]" >> $OutputDump 462 | fi 463 | else 464 | echo "FROM version file not found, skipping patch generation. ["$patchrefbin"]" >> $OutputDump 465 | fi 466 | fi 467 | fi 468 | fi 469 | fi 470 | fi 471 | 472 | if [ $ret == 0 ]; then 473 | rm $sign 474 | rm $sfu 475 | rm $headerbin 476 | if [ -e "$segoff" ]; then 477 | rm $segoff 478 | fi 479 | if [ -e "$signpatch" ]; then 480 | rm $signpatch 481 | fi 482 | if [ -e "$sfup" ]; then 483 | rm $sfup 484 | fi 485 | if [ -e "$keyfile" ]; then 486 | rm $keyfile 487 | fi 488 | if [ -e "$iv" ]; then 489 | rm $iv 490 | fi 491 | echo "Postbuild finished." 492 | exit 0 493 | else 494 | echo "$command : failed" >> $OutputDump 495 | if [ -e "$elf" ]; then 496 | rm $elf 497 | fi 498 | if [ -e "$elfbackup" ]; then 499 | rm $elfbackup 500 | fi 501 | echo $command : failed 502 | read -n 1 -s 503 | exit 1 504 | fi 505 | -------------------------------------------------------------------------------- /Scripts/make_keys_v6m.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo %0 : Generate new secure keys for stm32-secure-patching-bootloader and Cortex-M0 (V6M) architecture devices 4 | 5 | set _KEY_TOOL=..\Tools\prepareimage.py 6 | set _OUTPUT_DIR=%1 7 | 8 | if [%_OUTPUT_DIR%]==[] ( 9 | echo Please specify destination path to application Keys directory 10 | goto:eof 11 | ) 12 | 13 | if NOT EXIST %_KEY_TOOL% ( 14 | echo Key generation tool is not found %_KEY_TOOL% 15 | goto:eof 16 | ) 17 | 18 | 19 | set _CIPHER_KEY=Cipher_Key_AES_CBC.bin 20 | set _SIGNING_KEY=Signing_PrivKey_ECC.txt 21 | set _MACHINE_FILE=machine.txt 22 | 23 | echo Making %_OUTPUT_DIR%/%_CIPHER_KEY% 24 | python %_KEY_TOOL% keygen -k %_OUTPUT_DIR%\%_CIPHER_KEY% -t aes-cbc 25 | 26 | echo Making %_OUTPUT_DIR%/%_SIGNING_KEY% 27 | python %_KEY_TOOL% keygen -k %_OUTPUT_DIR%\%_SIGNING_KEY% -t ecdsa-p256 28 | 29 | echo Making %_OUTPUT_DIR%/%_MACHINE_FILE% 30 | echo V6M > %_OUTPUT_DIR%/%_MACHINE_FILE% 31 | 32 | -------------------------------------------------------------------------------- /Scripts/make_keys_v7m.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo %0 : Generate new secure keys for stm32-secure-patching-bootloader and Cortex-M3/M4/M7 (V7M and later) architecture devices 4 | 5 | set _KEY_TOOL=..\Tools\prepareimage.py 6 | set _OUTPUT_DIR=%1 7 | 8 | if [%_OUTPUT_DIR%]==[] ( 9 | echo Please specify destination path to application Keys directory 10 | goto:eof 11 | ) 12 | 13 | if NOT EXIST %_KEY_TOOL% ( 14 | echo Key generation tool is not found %_KEY_TOOL% 15 | goto:eof 16 | ) 17 | 18 | 19 | set _CIPHER_KEY=Cipher_Key_AES_CBC.bin 20 | set _SIGNING_KEY=Signing_PrivKey_ECC.txt 21 | set _MACHINE_FILE=machine.txt 22 | 23 | echo Making %_OUTPUT_DIR%/%_CIPHER_KEY% 24 | python %_KEY_TOOL% keygen -k %_OUTPUT_DIR%\%_CIPHER_KEY% -t aes-cbc 25 | 26 | echo Making %_OUTPUT_DIR%/%_SIGNING_KEY% 27 | python %_KEY_TOOL% keygen -k %_OUTPUT_DIR%\%_SIGNING_KEY% -t ecdsa-p256 28 | 29 | echo Making %_OUTPUT_DIR%/%_MACHINE_FILE% 30 | echo V7M > %_OUTPUT_DIR%/%_MACHINE_FILE% 31 | 32 | -------------------------------------------------------------------------------- /Test/B-L072Z-LRWAN1/BOOT_TestApp_B-L072Z-LRWAN1_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/B-L072Z-LRWAN1/BOOT_TestApp_B-L072Z-LRWAN1_v1.4.0.bin -------------------------------------------------------------------------------- /Test/B-L072Z-LRWAN1/TestApp_B-L072Z-LRWAN1_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/B-L072Z-LRWAN1/TestApp_B-L072Z-LRWAN1_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/B-L072Z-LRWAN1/TestApp_B-L072Z-LRWAN1_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/B-L072Z-LRWAN1/TestApp_B-L072Z-LRWAN1_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/B-L4S5I-IOT01A/BOOT_TestApp_B-L4S5I-IOT01A_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/B-L4S5I-IOT01A/BOOT_TestApp_B-L4S5I-IOT01A_v1.4.0.bin -------------------------------------------------------------------------------- /Test/B-L4S5I-IOT01A/TestApp_B-L4S5I-IOT01A_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/B-L4S5I-IOT01A/TestApp_B-L4S5I-IOT01A_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/B-L4S5I-IOT01A/TestApp_B-L4S5I-IOT01A_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/B-L4S5I-IOT01A/TestApp_B-L4S5I-IOT01A_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/DISCO-F469I/TestApp_DISCO-F469I_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-F469I/TestApp_DISCO-F469I_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/DISCO-F469I/TestApp_DISCO-F469I_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-F469I/TestApp_DISCO-F469I_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/DISCO-F769I/TestApp_DISCO-F769I_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-F769I/TestApp_DISCO-F769I_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/DISCO-F769I/TestApp_DISCO-F769I_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-F769I/TestApp_DISCO-F769I_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/DISCO-H745I/TestApp_DISCO-H745I_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-H745I/TestApp_DISCO-H745I_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/DISCO-H745I/TestApp_DISCO-H745I_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-H745I/TestApp_DISCO-H745I_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/DISCO-L476G/BOOT_TestApp_DISCO-L476G_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-L476G/BOOT_TestApp_DISCO-L476G_v1.4.0.bin -------------------------------------------------------------------------------- /Test/DISCO-L476G/TestApp_DISCO-L476G_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-L476G/TestApp_DISCO-L476G_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/DISCO-L476G/TestApp_DISCO-L476G_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-L476G/TestApp_DISCO-L476G_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/DISCO-L496G/BOOT_TestApp_DISCO-L496G_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-L496G/BOOT_TestApp_DISCO-L496G_v1.4.0.bin -------------------------------------------------------------------------------- /Test/DISCO-L496G/TestApp_DISCO-L496G_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-L496G/TestApp_DISCO-L496G_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/DISCO-L496G/TestApp_DISCO-L496G_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-L496G/TestApp_DISCO-L496G_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/DISCO-L4R9I/TestApp_DISCO-L4R9I_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-L4R9I/TestApp_DISCO-L4R9I_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/DISCO-L4R9I/TestApp_DISCO-L4R9I_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-L4R9I/TestApp_DISCO-L4R9I_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/DISCO-L562E/BOOT_TestApp_DISCO-L562E_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-L562E/BOOT_TestApp_DISCO-L562E_v1.4.0.bin -------------------------------------------------------------------------------- /Test/DISCO-L562E/TestApp_DISCO-L562E_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-L562E/TestApp_DISCO-L562E_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/DISCO-L562E/TestApp_DISCO-L562E_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/DISCO-L562E/TestApp_DISCO-L562E_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/L073RZ-NUCLEO/BOOT_TestApp_L073RZ-NUCLEO_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/L073RZ-NUCLEO/BOOT_TestApp_L073RZ-NUCLEO_v1.4.0.bin -------------------------------------------------------------------------------- /Test/L073RZ-NUCLEO/TestApp_L073RZ-NUCLEO_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/L073RZ-NUCLEO/TestApp_L073RZ-NUCLEO_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/L073RZ-NUCLEO/TestApp_L073RZ-NUCLEO_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/L073RZ-NUCLEO/TestApp_L073RZ-NUCLEO_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/LORA-E5-DEV/BOOT_TestApp_LORA-E5-DEV_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/LORA-E5-DEV/BOOT_TestApp_LORA-E5-DEV_v1.4.0.bin -------------------------------------------------------------------------------- /Test/LORA-E5-DEV/TestApp_LORA-E5-DEV_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/LORA-E5-DEV/TestApp_LORA-E5-DEV_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/LORA-E5-DEV/TestApp_LORA-E5-DEV_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/LORA-E5-DEV/TestApp_LORA-E5-DEV_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/NUCLEO-F429ZI/BOOT_TestApp_NUCLEO-F429ZI_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-F429ZI/BOOT_TestApp_NUCLEO-F429ZI_v1.4.0.bin -------------------------------------------------------------------------------- /Test/NUCLEO-F429ZI/TestApp_NUCLEO-F429ZI_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-F429ZI/TestApp_NUCLEO-F429ZI_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/NUCLEO-F429ZI/TestApp_NUCLEO-F429ZI_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-F429ZI/TestApp_NUCLEO-F429ZI_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/NUCLEO-G0B1RE/BOOT_TestApp_NUCLEO-G0B1RE_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-G0B1RE/BOOT_TestApp_NUCLEO-G0B1RE_v1.4.0.bin -------------------------------------------------------------------------------- /Test/NUCLEO-G0B1RE/TestApp_NUCLEO-G0B1RE_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-G0B1RE/TestApp_NUCLEO-G0B1RE_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/NUCLEO-G0B1RE/TestApp_NUCLEO-G0B1RE_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-G0B1RE/TestApp_NUCLEO-G0B1RE_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/NUCLEO-L412KB/BOOT_TestApp_NUCLEO-L412KB_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L412KB/BOOT_TestApp_NUCLEO-L412KB_v1.4.0.bin -------------------------------------------------------------------------------- /Test/NUCLEO-L412KB/TestApp_NUCLEO-L412KB_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L412KB/TestApp_NUCLEO-L412KB_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/NUCLEO-L412KB/TestApp_NUCLEO-L412KB_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L412KB/TestApp_NUCLEO-L412KB_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/NUCLEO-L452RE/BOOT_TestApp_NUCLEO-L452RE_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L452RE/BOOT_TestApp_NUCLEO-L452RE_v1.4.0.bin -------------------------------------------------------------------------------- /Test/NUCLEO-L452RE/TestApp_NUCLEO-L452RE_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L452RE/TestApp_NUCLEO-L452RE_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/NUCLEO-L452RE/TestApp_NUCLEO-L452RE_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L452RE/TestApp_NUCLEO-L452RE_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/NUCLEO-L476RG/BOOT_TestApp_NUCLEO-L476RG_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L476RG/BOOT_TestApp_NUCLEO-L476RG_v1.4.0.bin -------------------------------------------------------------------------------- /Test/NUCLEO-L476RG/TestApp_NUCLEO-L476RG_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L476RG/TestApp_NUCLEO-L476RG_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/NUCLEO-L476RG/TestApp_NUCLEO-L476RG_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L476RG/TestApp_NUCLEO-L476RG_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/NUCLEO-L496ZG/BOOT_TestApp_NUCLEO-L496ZG_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L496ZG/BOOT_TestApp_NUCLEO-L496ZG_v1.4.0.bin -------------------------------------------------------------------------------- /Test/NUCLEO-L496ZG/TestApp_NUCLEO-L496ZG_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L496ZG/TestApp_NUCLEO-L496ZG_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/NUCLEO-L496ZG/TestApp_NUCLEO-L496ZG_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-L496ZG/TestApp_NUCLEO-L496ZG_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/NUCLEO-WL55JC/BOOT_TestApp_NUCLEO-WL55JC_v1.4.0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-WL55JC/BOOT_TestApp_NUCLEO-WL55JC_v1.4.0.bin -------------------------------------------------------------------------------- /Test/NUCLEO-WL55JC/TestApp_NUCLEO-WL55JC_v1.4.0_v1.4.1.sfbp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-WL55JC/TestApp_NUCLEO-WL55JC_v1.4.0_v1.4.1.sfbp -------------------------------------------------------------------------------- /Test/NUCLEO-WL55JC/TestApp_NUCLEO-WL55JC_v1.4.1.sfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Test/NUCLEO-WL55JC/TestApp_NUCLEO-WL55JC_v1.4.1.sfb -------------------------------------------------------------------------------- /Test/README.md: -------------------------------------------------------------------------------- 1 | ## STM32 Secure Patching Bootloader Board Test Instructions 2 | 3 | 1. Load `BOOT_TestApp__vX.Y.0.bin` to the target with STM32CubeProgrammer. 4 | 2. Connect terminal program (e.g. TeraTerm) to board's VCOM port @ 115200,N,8,1. Power cycle or reset board. 5 | 3. Select update method: YMODEM from bootloader (hold user button while restarting, or paste code `load` during appropriate stage in boot process), or YMODEM from TestApp. 6 | 4. Test full image update: transfer `TestApp__vX.Y.1.sfb` via terminal program YMODEM. 7 | 5. Or test patch update: transfer `TestApp__vX.Y.0_vX.Y.1.sfbp` via terminal program YMODEM. 8 | 6. Or on boards that support USB OTG host, place files onto USB flash stick and have it inserted/connected to adapter connected to USB OTG port while restarting board. 9 | -------------------------------------------------------------------------------- /Tools/README.md: -------------------------------------------------------------------------------- 1 | ## STM32 Secure Patching Bootloader 2 | 3 | ## Tools 4 | 5 | These mostly Python tools serve two purposes: 6 | 1. Generate your application's firmware artifacts by postbuild script: combined bootloader+application .bin or .hex, firmware update files .sfb or .sfbp (patch). 7 | 2. Generate your application's secure keys: ECDSA and AES keys by make_keys script. 8 | 9 | The [JojoDiff](http://jojodiff.sourceforge.net/) difference tool `jdiff.exe` v0.8.1 is obtained from https://sourceforge.net/projects/jojodiff/. 10 | 11 | 12 | To use these scripts you need to make sure you have installed the appropriate Python modules listed in "requirements.txt": 13 | 14 | * `pip install -r requirements.txt` 15 | 16 | The scripts have been tested to work with Python 3.8.0 or later. 17 | 18 | 19 | -------------------------------------------------------------------------------- /Tools/jdiff.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firmwaremodules/stm32-secure-patching-bootloader/40c561d34a175182db3935524fe568c19f572b91/Tools/jdiff.exe -------------------------------------------------------------------------------- /Tools/keys.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2018 STMicroelectronics International N.V. 2 | # Copyright 2017 Linaro Limited 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # 17 | # Copyright (c) 2021-2022 Firmware Modules Inc. 18 | # 19 | # Permission is hereby granted, free of charge, to any person obtaining a copy 20 | # of this software and associated documentation files(the "Software"), to deal 21 | # in the Software without restriction, including without limitation the rights 22 | # to use, copy, modify, merge, publish, distribute, sublicense, and /or sell 23 | # copies of the Software, and to permit persons to whom the Software is 24 | # furnished to do so, subject to the following conditions : 25 | # 26 | # The above copyright notice and this permission notice shall be included in all 27 | # copies or substantial portions of the Software. 28 | # 29 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 30 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 31 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 32 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 33 | # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 34 | # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 35 | # OR OTHER DEALINGS IN THE SOFTWARE. 36 | # 37 | 38 | import os 39 | from Cryptodome.Cipher import AES 40 | from Cryptodome.Hash import SHA256 41 | from ecdsa import SigningKey, NIST256p, util 42 | import hashlib 43 | from struct import pack 44 | import translate_key_opcode as translate_key 45 | #for AES_CBC lambda pad to 16 bytes by adding the padded value 46 | #(i.e 24 bytes : 0x08 is added 8 times 47 | BS = 16 48 | pad = lambda s: s + (BS - len(s) % BS) * pack("B", 0) 49 | 50 | class AES_CBC(): 51 | def __init__(self, key): 52 | """Construct an AES_CBC private key with the given key data""" 53 | self.key = key 54 | self.nonce = [] 55 | @staticmethod 56 | def generate(): 57 | #use random from platform 58 | return AES_CBC(os.urandom(16)) 59 | def export_private(self, path): 60 | if "AES_CBC" not in path: 61 | print("path does not contains AES_CBC : AES_CBC key should contain AES_CBC string!!!") 62 | exit(1) 63 | else: 64 | with open(path, 'wb') as f: 65 | f.write(self.key) 66 | def encrypt(self, payload, nonce=[]): 67 | if payload == []: 68 | print("error") 69 | #Fix me AES CBC is possibly 12 bytes 70 | if nonce == []: 71 | nonce = os.urandom(16) 72 | m = hashlib.sha256() 73 | print("block size ="+str(AES.block_size)) 74 | encryptor = AES.new(self.key, AES.MODE_CBC, nonce) 75 | encrypted = "" 76 | #check if buffer size is aligned on BS size 77 | if (0 == (len(payload) % BS)): 78 | # we do not need to pad 79 | buffer=payload 80 | encrypted = encryptor.encrypt(buffer) 81 | else: 82 | # Buffer size is not correct (and we do not support ciphertext stealing mode "CBC-CS2" specified in NIST SP 800-38A any more) 83 | raise Exception("AES CBC encryption requires the Firmware Image size to be a multiple of the AES block size (16 bytes)") 84 | #compute sh256 on clear buffer without padding 85 | m.update(payload) 86 | signature = m.digest() 87 | #swap the last two block and truncate if required 88 | return encrypted,signature, nonce 89 | def trans(self,section, name, end, assembly, version): 90 | outcode = translate_key.function(section, name,assembly) 91 | code, bin = translate_key.translate(self.key,end,assembly, version) 92 | outcode += code 93 | return outcode 94 | def trans_bin(self, version): 95 | code, bin = translate_key.translate(self.key, version=version) 96 | return bin 97 | def has_nonce(self): 98 | return True 99 | def has_sign(self): 100 | return False 101 | def has_encrypt(self): 102 | return True 103 | 104 | class AES_GCM(): 105 | def __init__(self, key): 106 | """Construct an AES_GCM private key with the given key data""" 107 | self.key = key 108 | self.nonce = [] 109 | @staticmethod 110 | def generate(): 111 | #use random from platform 112 | return AES_GCM(os.urandom(16)) 113 | def export_private(self, path): 114 | if "AES_CBC" in path: 115 | print("path contains AES_CBC : AES_GCM key should not contain AES_CBC!!!") 116 | exit(1) 117 | else: 118 | with open(path, 'wb') as f: 119 | f.write(self.key) 120 | def encrypt(self, payload, nonce=[]): 121 | if payload == []: 122 | print("error") 123 | 124 | if nonce == []: 125 | nonce = os.urandom(12) 126 | encryptor = AES.new(self.key, AES.MODE_GCM, nonce) 127 | encrypted = encryptor.encrypt(payload) 128 | signature = encryptor.digest() 129 | return encrypted,signature, nonce 130 | def sign(self,payload, nonce): 131 | encryptor = AES.new(self.key, AES.MODE_GCM, nonce) 132 | encryptor.update(payload) 133 | signature = encryptor.digest() 134 | return signature, nonce 135 | def trans(self,section, name, end, assembly, version): 136 | outcode = translate_key.function(section, name,assembly) 137 | code, bin = translate_key.translate(self.key,end,assembly, version) 138 | outcode += code 139 | return outcode 140 | def trans_bin(self, version): 141 | code, bin = translate_key.translate(self.key, version=version) 142 | return bin 143 | def has_nonce(self): 144 | return True 145 | def has_sign(self): 146 | return True 147 | def has_encrypt(self): 148 | return True 149 | 150 | 151 | class ECDSA256P1(): 152 | def __init__(self, key): 153 | """Construct an ECDSA P-256 private key""" 154 | self.key = key 155 | 156 | @staticmethod 157 | def generate(): 158 | return ECDSA256P1(SigningKey.generate(curve=NIST256p)) 159 | 160 | def export_private(self, path): 161 | with open(path, 'wb') as f: 162 | f.write(self.key.to_pem()) 163 | def trans(self,section, name, end, assembly, version): 164 | vk = self.key.get_verifying_key() 165 | binarykey = vk.to_string() 166 | #generate asm code 167 | outcode = translate_key.function(section, name,assembly) 168 | code, bin = translate_key.translate(binarykey,end,assembly, version) 169 | outcode += code 170 | return outcode 171 | def trans_bin(self, version): 172 | vk = self.key.get_verifying_key() 173 | binarykey = vk.to_string() 174 | #generate assembled asm code 175 | code, bin = translate_key.translate(binarykey, version=version) 176 | #print(code) 177 | return bin 178 | def sign(self, payload): 179 | # To make this fixed length, possibly pad with zeros. 180 | sig = self.key.sign(payload, hashfunc=hashlib.sha256) 181 | return sig 182 | 183 | def has_nonce(self): 184 | return False 185 | def has_sign(self): 186 | return True 187 | 188 | def has_encrypt(self): 189 | return False 190 | 191 | 192 | def load(path): 193 | with open(path, 'rb') as f: 194 | pem = f.read() 195 | if len(pem) == 16: 196 | if "AES_CBC" in path: 197 | return AES_CBC(pem) 198 | else: 199 | return AES_GCM(pem) 200 | else: 201 | key = SigningKey.from_pem(pem) 202 | if key.curve.name == 'NIST256p': 203 | return ECDSA256P1(key) 204 | else: 205 | raise Exception("Unsupported") 206 | 207 | 208 | -------------------------------------------------------------------------------- /Tools/requirements.txt: -------------------------------------------------------------------------------- 1 | pycryptodome 2 | pycryptodomex 3 | ecdsa 4 | pyelftools 5 | intelhex 6 | -------------------------------------------------------------------------------- /Tools/translate_key_opcode.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2018 STMicroelectronics International N.V. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Copyright (c) 2021 Firmware Modules Inc. 16 | # 17 | # Permission is hereby granted, free of charge, to any person obtaining a copy 18 | # of this software and associated documentation files(the "Software"), to deal 19 | # in the Software without restriction, including without limitation the rights 20 | # to use, copy, modify, merge, publish, distribute, sublicense, and /or sell 21 | # copies of the Software, and to permit persons to whom the Software is 22 | # furnished to do so, subject to the following conditions : 23 | # 24 | # The above copyright notice and this permission notice shall be included in all 25 | # copies or substantial portions of the Software. 26 | # 27 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 29 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 30 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 31 | # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 32 | # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 33 | # OR OTHER DEALINGS IN THE SOFTWARE. 34 | 35 | import os 36 | from array import array 37 | from struct import pack 38 | 39 | 40 | def reglistR1(endreg): 41 | # Fill bits in reglist bitfield, excluding R0, R1 up to endreg 42 | return (((1 << (endreg + 1)) - 1) & 0xfffe) 43 | 44 | def opSTMR0v7(bin, endreg): 45 | # STM.W Rn, 46 | # 1110 1000 1000 nnnn 000r rrrr rrrr rrrr 47 | # Note we MUST NOT USE WRITEBACK (!) because R0 is incremented by a subsequent ADDS instruction 48 | opcode = 0xE8800000 | reglistR1(endreg) 49 | appendOpcode32(bin, opcode) 50 | 51 | 52 | 53 | def opSTMR0v6(bin, endreg): 54 | # STM R0!, {R1, Rendreg } 55 | # 11000 000 xxxxxxx0 <--- 8 bits, each bit sets a register to copy, R0-R7 56 | # Note in thumb T1, writeback (!) is always set/true, so R0! is not required. 57 | opcode = 0xC000 | reglistR1(endreg) 58 | appendOpcode16(bin, opcode) 59 | 60 | 61 | def opPUSHR1R5(bin): 62 | # PUSH {R1, R5} 63 | # 1011 0 10 0 xxxxxxx0 64 | opcode = 0xB400 | reglistR1(5) 65 | appendOpcode16(bin, opcode) 66 | 67 | def opPOPR1R5(bin): 68 | # POP {R1, R5} 69 | # 1011 1 10 0 xxxxxxx0 70 | opcode = 0xBC00 | reglistR1(5) 71 | appendOpcode16(bin, opcode) 72 | 73 | def opBXLR(bin): 74 | # BX LR (R14) 75 | # 010001 11 0 xxxx 000 - > 0100 0111 0111 0000 76 | opcode = 0x4770 77 | appendOpcode16(bin, opcode) 78 | 79 | 80 | def opADDR0v6(bin, imm): 81 | # ADDS R0, R0, #imm 82 | # 001 10 000 xxxxxxxx 83 | opcode = 0x3000 | (imm & 0xFF) 84 | appendOpcode16(bin, opcode) 85 | 86 | def opADDR0v7(bin, imm): 87 | # ADDS.W R0, R0, #imm 88 | # Encoding T3 to match output of GCC assembler for "ADD R0, R0, #16". 89 | opcode = 0xF1000000 | (imm & 0xFF) 90 | appendOpcode32(bin, opcode) 91 | 92 | def opADDSv6(bin, Rd, Rn, Rm): 93 | # ADDS Rd, Rn, Rm T1 94 | # 000 11 00 mmm nnn ddd -> 0001 100m mmnn nddd 95 | opcode = 0x1800 96 | opcode |= ((Rd & 0x7) << 0) 97 | opcode |= ((Rn & 0x7) << 3) 98 | opcode |= ((Rm & 0x7) << 6) 99 | appendOpcode16(bin, opcode) 100 | 101 | def opADDv6(bin, Rd, Rm): 102 | # ADDS Rdn, Rm (Rd = Rn) T2 103 | # 010001 000 mmmm ddd -> 0100 0100 0mmm mddd 104 | opcode = 0x4400 105 | opcode |= ((Rd & 0x7) << 0) 106 | opcode |= ((Rm & 0xf) << 3) 107 | appendOpcode16(bin, opcode) 108 | 109 | def opMOVSv6(bin, destreg, imm): 110 | # MOVS Rd, #imm8 111 | # 001 00 ddd xxxxxxxx 112 | opcode = 0x2000 113 | opcode |= ((destreg & 0x7) << 8) 114 | opcode |= (imm & 0xff) 115 | appendOpcode16(bin, opcode) 116 | 117 | def opLSLSv6(bin, destreg, imm): 118 | # LSLS Rd, Rm, #imm5 (Rd = Rm) 119 | # 000 00 xxxxx mmm ddd 120 | opcode = 0x0000 121 | opcode |= ((destreg & 0x7) << 3) 122 | opcode |= ((destreg & 0x7) << 0) 123 | opcode |= ((imm & 0x1f) << 6) 124 | appendOpcode16(bin, opcode) 125 | 126 | def opMOVIMMv7(imm): 127 | # MOVX Rd, #imm16 128 | # 11110 x 100100 xxxx 0 xxx dddd xxxxxxxx -> 1111 0x10 0100 xxxx 0xxx dddd xxxxxxxx 129 | # xxxxxxxxxxxxxxxx................ 130 | # xxxxxxxxxxxxxxxx........ 131 | # xxxxxxxxxxxxxxxx...... 132 | opcode = 0 133 | opcode |= ((imm & 0xF000) << 4) # imm4 top 4 bits moved up 4 bits to land at [3-0] in upper word 134 | opcode |= ((imm & 0x0800) << 15) # i bit 11 moved up into bit 10 of upper word 135 | opcode |= ((imm & 0x0700) << 4) # imm3 [10-8] moved up to bits [14-12] of lower word 136 | opcode |= ((imm & 0x00FF) << 0) # imm8 [7-0] copied straight over to [7-0] of lower word 137 | return opcode 138 | 139 | def opMOVWv7(bin, destreg, imm): 140 | # MOVW Rd, #imm16 141 | # 11110 x 100100 xxxx 0 xxx dddd xxxxxxxx -> 1111 0x10 0100 xxxx 0xxx dddd xxxxxxxx 142 | opcode = 0xF2400000 143 | opcode |= ((destreg & 0xf) << 8) 144 | opcode |= opMOVIMMv7(imm) 145 | appendOpcode32(bin, opcode) 146 | 147 | 148 | def opMOVTv7(bin, destreg, imm): 149 | # MOVT Rd, #imm16 150 | # 11110 x 101100 xxxx 0 xxx dddd xxxxxxxx -> 1111 0x10 1100 xxxx 0xxx dddd xxxxxxxx 151 | # xxxxxxxxxxxxxxxx................ 152 | # xxxxxxxxxxxxxxxx........ 153 | # xxxxxxxxxxxxxxxx...... 154 | opcode = 0xF2C00000 155 | opcode |= ((destreg & 0xf) << 8) 156 | opcode |= opMOVIMMv7(imm) 157 | appendOpcode32(bin, opcode) 158 | 159 | def appendOpcode16(bin, opcode): 160 | bin += pack('> 16) & 0xffff) 164 | bin += pack('