Secure bootloader chain + two-stage upgradable bootloader MCUBOOT

I am working with nRF connect SDK with nRF5340DK. I am compiling code using nRF connect (ncs-1.8.0) for VS code with nrf5340dk_nrf5340_cpuapp board.

prj.conf as below,

CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_MCUMGR=y
CONFIG_SECURE_BOOT=y
Using this I can enabling two-stage bootloader, here are the log,
 
*** Booting Zephyr OS build v2.7.0-ncs1 ***

Attempting to boot slot 0.

Attempting to boot from address 0x8200.

Verifying signature against key 0.

Hash: 0x12...93

Firmware signature verified.

Firmware version 1

Booting (0x8200).

*** Booting Zephyr OS build v2.7.0-ncs1 ***

I: Starting bootloader
I: Primary image: magic=good, swap_type=0x3, copy_done=0x1, image_ok=0x1
I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
I: Boot source: none
I: Swap type: none
I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
I: Boot source: none
I: Bootloader chainload address offset: 0x28000
I: Jumping to the first image slot
*** Booting Zephyr OS build v2.7.0-ncs1 ***
I can firmware upgrade over-the-air (FOTA) for application using app_update.bin file.
Question:
1) How can I upgrade the second stage bootloader(MCUBoot bootloader)?
2) Which bin file to upload for upgrade the second stage bootloader?
Parents
  • Hi Siddharth, 

    I would suggest to have a look at this case to have an idea of how it should be handled: https://devzone.nordicsemi.com/f/nordic-q-a/67024/nrf9160-questions-related-to-immutable-mcuboot-application/274813#274813

    Then you can have a look at this case , our coworker has created a working example: 

    https://devzone.nordicsemi.com/f/nordic-q-a/85539/update-mcuboot-with-smp/358748

  • Hi Hung,

    I have tried your coworker example : https://devzone.nordicsemi.com/f/nordic-q-a/85539/update-mcuboot-with-smp/358748

    but its not updating MCUBOOT!!

     For, testing I had follow below steps,

    I make a change to MCUBoot, for example add a log in $NRF_CONNECT_SDK/bootloader/mcuboot/boot/zephyr/main.c.

    Build again, and upload the new image using mcumgr:

    mcumgr conn add acm0 type="serial" connstring="dev=/dev/ttyACM0,baud=115200,mtu=512"
    mcumgr -c acm0 image list
    mcumgr -c acm0 image upload build/zephyr/signed_by_mcuboot_and_b0_s1_image_update.bin
    mcumgr -c acm0 image list
    

    Copy the hash of the newly uploaded image, and use it to confirm it, making the new image run at next reboot, such as:

    mcumgr -c acm0 image confirm 2348de4f84cb19c1c2721662ad1275da5c21eca749da9b32db20d2c9dffb47c0
    

    Then reboot the Developement Kit. This will load the new MCUBoot image its slot. Reboot the Developement Kit again to load using the new version of MCUBoot.

    If I miss any steps let me know please.

    I did not Disable the Mass Storage feature on the device. is this required to do that?

    Why required Disabling the Mass Storage feature on the device? 

    Also I have one questions,

    How we can use both stage bootloader as MCUBOOT? as shown in below ,I am talking about second options.

    Bootloader

    Can be first-stage

    Can be second-stage

    Key type support

    Public key revocation

    SMP updates

    Downgrade protection

    Versioning

    Update methods (supported by nRF Connect SDK)

    nRF Secure Immutable Bootloader

    Yes

    No

    See list

    Yes

    No

    Yes

    Monotonic (HW)

    Dual slot execute in place (XIP)

    MCUboot

    Yes

    Yes

    See imgtool

    No

    Yes

    Yes

    Semantic (SW)

    Image swap - single primary

  • Hi Siddharth,

    Could you explain what the result of your test ? 

    You mentioned that "its not updating MCUBOOT!!" so what happened ? 

    The MCUBoot can be used as first stage bootloader. But could you explain what your plan by having MCUBoot in both stages  ? 

  • Hi Hung,

    I have added print line on this path : $NRF_CONNECT_SDK/bootloader/mcuboot/boot/zephyr/main.c.

    So, after this changes I have pristine build the code in vs code and then after I have upload the signed_by_mcuboot_and_b0_s1_image_update.bin file then after confirm with hash key.

    • you can see the below pic of mcumgr for upload cmd

    • Below is confirm cmd pic, you can see after this cmd flag change is also changed to pending permanent.

    • After this I have to reboot the board with reset switch and here is log of 1st reset, you can see

    "swap type : perm" and that time it takes some time to doing swapping the image

    • Reboot the Developement Kit again with reset switch, below is log of that. I had chenge FW: v2.0.0(when I Build signed_by_mcuboot_and_b0_s1_image_update.bin for new upgrading image) witch is not updated so means MCUBOOT is not updated. correct?

    • Below is Image list cmd pic. you can see that active confirmed hash is same, so means that it is booting with same image.. not a new image


    The MCUBoot can be used as first stage bootloader. But could you explain what your plan by having MCUBoot in both stages  ? 

    mainly my purpose is to upgrade the bootloader

  • Hi Siddharth,

    I will continue helping you in this case.

    When you use MCUBoot to update the application, the application is is kept in the expected slot.
    However, when updating MCUBoot, it is a two-step process:
    1. Upload mcuboot image into slot.
    2. Swap image from slot with previous mcuboot image.

    I think this is to allow rolling back to the previous image if the update fails.

    So you will not be able to list MCUBoot versions using mcumgr as you can for the application.

    You will however get the hash from the previous image in said slot.

    However, changes you made to MCUBoot (such as updating the print) should be active.

    To test this, I add the following to $NRF_CONNECT_SDK/bootloader/mcuboot/boot/zephyr/main.c:

    464     BOOT_LOG_INF("Starting bootloader");
    465     BOOT_LOG_INF("Bootloader version: %d\n",CONFIG_FW_INFO_FIRMWARE_VERSION);
    

    This way, it will automatically print my config from child_image/mcuboot/prj.conf

    To be extra certain, I also added a log for AAAAA.
    In this case, my log on serial output looks as following:

    And since both the fw number and the print is updated, we can see that MCUBoot is updated.

    Does this answer yout questions?

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd,

    Thanks for the detail explanation. I got your point. I will test it again as you explain and if I face any difficulty then let you know.

  • Hi Sigurd,

    Now, I am able to do upgrade the mcuboot.

    I have questions regarding KEY.

    1) how can I generate my own "custom_priv.pem" which is CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256?

    2) how can I generate my own "nsib_priv.pem" which is CONFIG_SB_SIGNING_KEY_FILE? what is type of this key?

Reply Children
  • Hi Siddharth,

    Siddharth Kachhia said:
    1) how can I generate my own "custom_priv.pem" which is CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256?

    As long as it is a standard ECDSA P256 key, you should be able to use any tool. For example OpenSSl. However, the MCUBoot tool imgtool.py has functionality for creating such keys, so I recommend it:

    python3 <nrf_connect_sdk_dir>/bootloader/mcuboot/scripts/imgtool.py keygen -k filename.pem -t ecdsa-p256
    

    Siddharth Kachhia said:
    2) how can I generate my own "nsib_priv.pem" which is CONFIG_SB_SIGNING_KEY_FILE? what is type of this key?

    From nRF Secure Immutable Bootloader documentation:
    "This bootloader supports the ECDSA-p256 key type for validating the next image in the boot chain."

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd,

    Thanks for the quick reply. got it point. I will try to create ECDS_P256 key using imgtool.py 

    I have question on network core bootloader.

    Is it possible to enable secure bootloader chain (two stage upgradable bootloader MCUBOOT) on network core?

    So, at the end I want to achieve below things,
    Upgrade MCUboot and application on application core,
    Upgrade MCUboot and application on network core.

  • Hi

    By default, the Network Core does not run MCUBoot, but a custom bootloader called b0n: nRF5340: Network core bootloader.
    Therefore, if you need to update MCUBoot, this would be relevant mostly for the application core.

    I do not think we have any sample for running MCUBoot on the Network Core.
    I suspect that doing so will take up too much space to also run the Bluetooth Low Energy Host. But I have not verified this, so I recommend that you check this yourself if you want to be sure.

    As with NSIB in the Application core, I do not think it is possible to update this bootloader. At least not easily.
    If you have good reason for wanting to update either NSIB(b0) or b0n, I could ask our developers if this is possible?

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd,

    I was asking for feasibility. right now there is no any good point for upgrading that.

     In my current implementation,

    I have added secure bootloader chain in application core and after that I am able to do upgrade 2nd stage bootloader mcuboot(using signed_by_mcuboot_and_b0_s1_image_update.bin) and application core app (using app_update.bin). but not upgrading net-core app (using net_core_app_update.bin).

    Is there any thing missing?

    Because I have tested with single stage bootloader as mcuboot, I am able to upgrade application core app (using app_update.bin) and net-core app (using net_core_app_update.bin).

    Facing issue with multistage bootloader to upgrade net-core app.

  • Hi

    We do not support encrypted bootloader chain.

    Regards,
    Sigurd Hellesvik

Related