This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Replace existing Private Key in Bootloader with new one using DFU

Hello!

I have some devices with a custom built PCB on my desk, all of which have my own custom firmware on it.

Sadly the devices don't have access to the debug pins so I can only update via bluetooth.

When I first flashed these devices I flashed a full firmware package (bootloader, softdevice and application) which was based on a different firmware (let's call it OLD) I wrote some time ago.

This firmware package also includes the Secure BLE DFU Service so my plan was to update the devices later with the new firmware I am developing right now.

All good so far, I've done this before, no troubles yet.

Now I have finished to prepare my new firmware (let's call it NEW) and it's almost ready for production.

I realized that the bootloader I flashed before includes the private key of the OLD firmware.

I wanted to replace the private key in the NEW firmware to prevent the user from being able to flash the wrong firmware onto the wrong device, potentially killing it.

But now I have run into the problem that I am actually trying to avoid.

I have to update the existing firmware via bluetooth but I am unable to do so because my NEW firmware uses a new private key.

I have tried to create a temporary DFU distribution package containing the NEW bootloader (which has been compiled with the NEW private key) but signed with the OLD key.

Sadly that does not work. When trying this on an open PCB I have access to the RTT log I can see the following error output

00> :INFO:Image verified 
00> :INFO:Prevalidate FAILED!
00> :INFO:Sending Response: [0x4, 0x4]

So I guess replacing the bootloader with a different one is not possible?

Or am I missing something?

Would be a really really big shame if the devices I have flashed before are now at a dead end :( 

Any help is appreciated!

Also, big shout out to the Nordic staff and support team! The SDK and documentation you provide is great, as is the support you offer!

  • When opening the original firmware in the nRF Connect Programmer tool I can see the following layout

    Orange = MBR, 0x0 to 0x964

    Blue = Softdevice, 0x1000 to 0x1E740

    Green = Application, 0x1F000 to 0x3940C

    Red = Bootloader, 0x73000 to 0x7B1BC

    Black = Unkown (maybe the settings?), 0x7F000 to 0x7F05C

    So my old bootloader does exceed the 24kB you were talking about before by 12kB as it is 32kB in size.
    Could this cause such an issue?

    I checked, the new bootloader only takes 22kB.

    Also, the old softdevice takes 124kB of size, the new one needs 152kB. (as you said and I confirmed)

    When updating from the old one to the new one I'd expect the softdevice update to overwrite the application part of the old firmware, causing the application the device to become invalid.

    What would happen in such a case? Would the device be staying in DFU mode until I also send the new application?

  • mikoay said:

    Orange = MBR, 0x0 to 0x964

    Blue = Softdevice, 0x1000 to 0x1E740

    Green = Application, 0x1F000 to 0x3940C

    Red = Bootloader, 0x73000 to 0x7B1BC

    Black = Unkown (maybe the settings?), 0x7F000 to 0x7F05C

     Correct, black is the settings page. 

    The available flash memory for a dual bank update would in this case be 0x73000-0x3A000 = 0x39000 ( 228kB) so there should be plenty of room for the S132 v6.1.1 wihtout the MBR ( 148kB) + Bootloader (22kB) = 170kB. 

    We also need to take into account the DFU_APP_DATA_RESERVED settings, which reserves N number of pages below the bootloader for application data( e.g. bonding information). This is by default set to 3 pages, so that means that the actual available memory will be 0x70000-0x3A000 = 0x36000 ( 216kB). Which should still be more than enough. 

    mikoay said:
    So my old bootloader does exceed the 24kB you were talking about before by 12kB as it is 32kB in size.
    Could this cause such an issue?

     As long as the old bootloader is larger than the new bootloader there is no issue. But you need to make sure that the new bootloader is compiled with the same start address as the old one, i.e. 0x73000

    mikoay said:

    When updating from the old one to the new one I'd expect the softdevice update to overwrite the application part of the old firmware, causing the application the device to become invalid.

    What would happen in such a case? Would the device be staying in DFU mode until I also send the new application?

     The bootloader will only erase the old application if the space from the first unused flash page after the old application to the start of the reserved page section is smaller than the size of the firmware image with the SD+BL. In this case its not, so the BL will perform a dual bank update, i.e. keep the old application in flash. 

    If the old application is incompatible with the new softdevice, then it will be invalidated and the nRF device will stay in bootloader mode after the SD+ BL update is completed and wait for a new application update. 

  • I think there we might have the problem. Neutral face

    The old bootloader starts at 0x73000

    The new bootloader starts at 0x78000

    So if I understood you correctly that's one of the requirements to be able to properly update the bootloader, right?

    In other words, I am out of luck and I can't replace the old bootloader with the new one?

  • Yes, the new bootloader must be able to fit between 0x73000 and 0x7E000( start address of the MBR parameter page). The new bootloader is using S132 v6.1.1, so I assume this is the bootloader from SDK v15.3.0. The non-debug bootloader should only require 24kB, i.e. start address 0x78000 and size 0x6000 bytes , but If its the debug bootloader the size is 0xB000 and the start address is 0x73000. 

    Have you modified the debug bootloader? Can you switch to the non-debug bootloader?

Related