Author Topic: Custom STM32 bootloader guidance  (Read 3074 times)

0 Members and 1 Guest are viewing this topic.

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8001
  • Country: fi
Re: Custom STM32 bootloader guidance
« Reply #25 on: June 17, 2023, 07:07:09 am »
Yes, the only way to not waste that space is to use the more traditional bootloader method.
Where you have a bootloader space and an one APP space. The bootloader runs and talks to the outside world to receive new FW data and write them to the APP area.

The disadvantage with this is that the bootloader is more complicated and larger in size.
It needs to understand RS232/SPI/TCP/BLE or whatever method you use for FW updates, and include libraries for them.  So there is more risk of bugs.

IMHO, this is only really suitable for simple UART based updaters which are so simple they can be fully tested with 100% coverage, and interface locked at design time. You can alleviate the size issue by exposing the bootloader functions for application use, but then you are locked down to these implementations forever, in both bootloader and app. It's a total no-go IMHO, things like TLS implementations will have critical security bugs which need updating.
 

Offline darkspr1te

  • Frequent Contributor
  • **
  • Posts: 281
  • Country: zm
Re: Custom STM32 bootloader guidance
« Reply #26 on: June 17, 2023, 08:34:56 am »
As a user who has fallen prey to badly implemented bootloaders with little to no fail safe's , I can say its not a fun rabbit hole to go down.
Most implement a bootloader in it's own right with app being compiled ass separate entity ,
here is a example
https://github.com/darkspr1te/stm32f407_vet_bootloader/blob/master/platformio.ini
it for stm32f407 but the main code principle is the same for most stm, it looks for a bin file on sd-card and writes it to flash @0x4000 and then resets into it, (that just mean i load the vector table into ram and the reset into the new vector table)
or this one which has more complicated setup,
https://github.com/darkspr1te/mkstft35_bl_vet_fsmc
this one runs a small crc check as it reads the data , if crc fails it wont write, if it passes it's decrypted then written (it's open sources version of the nasty and stupid encrypted MKS robin bootloader )
I have many more code examples of bootloaders and apps in platformio / stm32cube base if needed, you will note most have a encrypt/decrypt option as i've found the need to hack quite a few badly done bootloaders in order to repair the device which has since bricked and more care was put into encrypting the IP than ensuring correct updates.


You will also find it hard to do the A/B flash space on many stm's you look at, even though I have implemented such myself on stm's and others  I have found it works best on spi flash based devices offering more /swappable memory space.
While most of my loaders work with sd-card/usb flash/uart over usb there are much more modern ones like the new st example which make the device appear as a flash card and you just drag and drop a bin file(a check is implemented that the first few bytes point into a proper vector table or it wont write) , or the older DFU version (buggy as heck even in silicon based DFU)


The main thing i have learned in all this re-writing bootloaders is it's key to allow bootloader activation even if firmware corrupts, one device i have always goes to bootloader if powered via USB yet it was not implemented ,it was there in the code but it was skipped by a prior instruction , bug or left test code i dont know but once i NOP'ed out that it allowed me to write correct firmware and it lived again.
another lesson is it's key to have a decent check method in place, for MKS they simply used RSA128 code to act as a form of crc but they made a mistake in the code in that it erased first, then checked the incoming packets for correct rsa sequence decrypt  and if they passed were written, if failed it would error out but has already started the erase procedure rendering the device bricked.


How you provide the firmware to the bootloader can also effect your implementation, a example would be if delivered via sd-card I have in the past used headers and footers added to the binary file that include crc data as as the complete file is available to the mcu then a crc check can be run on the entire file prior to writing, however if you sending via another method then you wont have the memory space normally to receive the entire file and then run a crc on it, this is where some implement transfer systems like zmodem/xmodem which have inbuilt packet based crc's and were common in modem days and are popular among some as the code is small and is the same for host/client making deployment a little easier.




That leads me onto the last item, the app that delivers the update service, also important. Again i have run foul of many badly done updaters that either fail due to age/windows support, driver support, dodgy chinese dll's requiring admin privilege's to just write to serial port ?  no valid file checking , no valid servers anymore my fav android issue  no BT device seen !. I have to maintain a windows 7 VM just for a few devices with PL2303 chips because windows has banned the driver and my OBD device has chinese spyware clear as day in it but it's the only way to clear out the saved reports, almost like they did that on purpose.
so if you can eliminate the update APP requirement you will remove one large headache.




darkspr1te

 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3591
  • Country: gb
  • Doing electronics since the 1960s...
Re: Custom STM32 bootloader guidance
« Reply #27 on: June 17, 2023, 10:19:48 am »
Quote
It's a total no-go IMHO, things like TLS implementations will have critical security bugs which need updating.

Anyone exposing an embedded box to the outside world is gonna have much bigger problems ;)

And if the embedded box is not exposed (is a client only, usually behind NAT) then security is a non-issue.

But we've done all this before :)

As in the other thread
https://www.eevblog.com/forum/microcontrollers/upgrade-firmware-by-end-user/msg4912849/#msg4912849
the choice will be according to other requirements.

Also whether and how firmware needs updating is a heavily political decision - as posted in the other thread.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26561
  • Country: nl
    • NCT Developments
Re: Custom STM32 bootloader guidance
« Reply #28 on: June 18, 2023, 08:39:51 am »
Yes, the only way to not waste that space is to use the more traditional bootloader method.
Where you have a bootloader space and an one APP space. The bootloader runs and talks to the outside world to receive new FW data and write them to the APP area.

The disadvantage with this is that the bootloader is more complicated and larger in size.
It needs to understand RS232/SPI/TCP/BLE or whatever method you use for FW updates, and include libraries for them.  So there is more risk of bugs.

IMHO, this is only really suitable for simple UART based updaters which are so simple they can be fully tested with 100% coverage, and interface locked at design time. You can alleviate the size issue by exposing the bootloader functions for application use, but then you are locked down to these implementations forever, in both bootloader and app. It's a total no-go IMHO, things like TLS implementations will have critical security bugs which need updating.
True. With the firmware update mechanism inside the firmware itself, you can always replace things like encryption algorithms and change the ways the firmware image is delivered / formatted.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3591
  • Country: gb
  • Doing electronics since the 1960s...
Re: Custom STM32 bootloader guidance
« Reply #29 on: June 18, 2023, 01:32:08 pm »
And brick some large volume of your product if it goes wrong :)

As I posted above, if it is on an open port, it's going to get trashed if somebody finds it (subject to an adequate attack surface e.g. the ability to access a filesystem and either DoS that or plant some executable in there, etc) regardless of some esoteric debate about MbedTLS vulnerabilities, and if it isn't on an open port then the crypto never needs to be updated because it will work "for ever".

Well, until the (public facing) server (to the back of which it is connecting to as a client) is forced to update. An example might be your box is using TLS 1.1 and 10 years down the road the server needs an upgrade and the lowest it supports is TLS 1.3 and then you are forced to update your box, with all the risk involved. I am facing this with my product. It should all work but the disaster potential is not wholly avoidable. Only extensive testing will minimise the risk. If it was me I would implement a TLS 1.1 interface on the said server and to hell with upgrading the client crypto. Nobody will find out.
« Last Edit: June 18, 2023, 03:00:24 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Georgy.Moshkin

  • Regular Contributor
  • *
  • Posts: 139
  • Country: hk
  • R&D Engineer
    • Electronic projects, modules and courses on Arduino and STM32
Re: Custom STM32 bootloader guidance
« Reply #30 on: June 18, 2023, 02:15:23 pm »
Bootloader rules I came up with during few years
1. write protected bootloader sector
2. readout protection is on
3. crc32 and retry mechanism
4. aes encrypted in software, easy to migrate
5. can enter to bootloader on reboot during 500ms window
6. a way to reboot without powering cycling
7. dma bridging between two usarts for flashing other MCU, e.g. esp8266
8. no swdio swdclk pins routed on final pcb

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3591
  • Country: gb
  • Doing electronics since the 1960s...
Re: Custom STM32 bootloader guidance
« Reply #31 on: June 18, 2023, 09:19:39 pm »
Quote
dma bridging between two usarts for flashing other MCU, e.g. esp8266

That's an interesting option. The 32F4 boot loader can flash the flash directly from serial uart data; whether it uses dma I don't know but there is no need to because programming is quite slow.

I remember someone telling me that having two CPUs is the only provably non-brickable way. I guess it is true. One of them is just a boot loader and feeds the data to the main CPU, with its serial boot loader activated.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Georgy.Moshkin

  • Regular Contributor
  • *
  • Posts: 139
  • Country: hk
  • R&D Engineer
    • Electronic projects, modules and courses on Arduino and STM32
Re: Custom STM32 bootloader guidance
« Reply #32 on: June 20, 2023, 04:47:31 am »
Quote
dma bridging between two usarts for flashing other MCU, e.g. esp8266

That's an interesting option. The 32F4 boot loader can flash the flash directly from serial uart data; whether it uses dma I don't know but there is no need to because programming is quite slow.

I remember someone telling me that having two CPUs is the only provably non-brickable way. I guess it is true. One of them is just a boot loader and feeds the data to the main CPU, with its serial boot loader activated.

Yes, probably DMA is not so important for bridging.  I have commands for write protecting of first sector and for setting RDP level. Theoretically, write protected bootloader may be overwritten, but this never happened to me.
Two CPU way is interesting too, maybe cheaper is to use some flash IC with bootloader pre-flashed, and route with WE pin tied to "write disabled" voltage level. After it is soldered, write protection is always on.


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf