Problem with signing images for OTA DFU

I have had several problems with signing images, so I'll start with something simple, and I hope you can bear with me as I get to my final goal which is to OTA (which I am already doing, but not signed) with the project we are working on.

I am testing everything on a nrf52dk_nrf52832 using both windows 10 and ubuntu 20 VM's and I have had similar problems with both of them. I am using NCS v1.3.2 in both cases. I am not a beginner in Zephyr, or Nordic in general for that matter, but I feel like one with the whole signing, mcumgr cli using the 840 as HCI_USB in ubuntu, etc

Firstly, there are two "how to " pages that do not work following directions, so if you would kindly tell me what is wrong with the instructions.

Please advice.

The first page is "Signing Binaries

Following instructions, the first line has no problem...

antonio@ubuntu:~/ncs$ west build -b nrf52dk_nrf52832 -s bootloader/mcuboot/boot/zephyr -d build-mcuboot

But then the next command line...

antonio@ubuntu:~/ncs$ west build -b nrf52dk_nrf52832 -s zephyr/samples/hello_world -d build-hello-signed -- -DCONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"bootloader/mcuboot/root-rsa-2048.pem\"

Comes with errors...

antonio@ubuntu:~/ncs$ west build -b nrf52dk_nrf52832 -s zephyr/samples/hello_world -d build-hello-signed -- -DCONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"bootloader/mcuboot/root-rsa-2048.pem\"

-- west build: generating a build system

Including boilerplate (Zephyr base): /home/antonio/ncs/zephyr/cmake/app/boilerplate.cmake

-- Application: /home/antonio/ncs/zephyr/samples/hello_world

-- Zephyr version: 2.3.0-rc1 (/home/antonio/ncs/zephyr)

-- Found Python3: /usr/bin/python3.8 (found suitable exact version "3.8.5") found components: Interpreter

-- Board: nrf52dk_nrf52832

-- Found west: /home/antonio/.local/bin/west (found suitable version "0.8.0", minimum required is "0.7.1")

-- Found dtc: /usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6")

-- Found toolchain: gnuarmemb (/opt/gnuarmemb)

-- Found BOARD.dts: /home/antonio/ncs/zephyr/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts

-- Generated zephyr.dts: /home/antonio/ncs/build-hello-signed/zephyr/zephyr.dts

-- Generated devicetree_unfixed.h: /home/antonio/ncs/build-hello-signed/zephyr/include/generated/devicetree_unfixed.h

Parsing /home/antonio/ncs/zephyr/Kconfig

Loaded configuration '/home/antonio/ncs/zephyr/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig'

Merged configuration '/home/antonio/ncs/zephyr/samples/hello_world/prj.conf'

Merged configuration '/home/antonio/ncs/build-hello-signed/zephyr/misc/generated/extra_kconfig_options.conf'

/home/antonio/ncs/build-hello-signed/zephyr/misc/generated/extra_kconfig_options.conf:3: warning: attempt to assign the value '"bootloader/mcuboot/root-rsa-2048.pem"' to the undefined symbol MCUBOOT_SIGNATURE_KEY_FILE

error: Aborting due to Kconfig warnings

CMake Error at /home/antonio/ncs/zephyr/cmake/kconfig.cmake:217 (message):

  command failed with return code: 1

Call Stack (most recent call first):

  /home/antonio/ncs/zephyr/cmake/app/boilerplate.cmake:506 (include)

  /home/antonio/ncs/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:24 (include)

  /home/antonio/ncs/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:35 (include_boilerplate)

  CMakeLists.txt:5 (find_package)

-- Configuring incomplete, errors occurred!

FATAL ERROR: command exited with status 1: /usr/bin/cmake -B/home/antonio/ncs/build-hello-signed -S/home/antonio/ncs/zephyr/samples/hello_world -GNinja -DBOARD=nrf52dk_nrf52832 -DCONFIG_BOOTLOADER_MCUBOOT=y '-DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/root-rsa-2048.pem"'

The second page is "SMP Server Sample"

Which, again, the build and flash for the mcu_boot works ok

west build -b <board> -d build_mcuboot bootloader/mcuboot/boot/zephyr

west flash -d build_mcuboot

But when you try the sample application…

west build \

   -b nrf52dk_nrf52832 \

   samples/subsys/mgmt/mcumgr/smp_svr \

   -- \


Works ok if you change your directory to zephyr, or if you alter the command to build fom ./ncs


But the signing has an error:

west sign -t imgtool -- --key bootloader/mcuboot/root-rsa-2048.pem

antonio@ubuntu:~/ncs$ west sign -t imgtool -- --key bootloader/mcuboot/root-rsa-2048.pem

=== image configuration:

partition offset: 49152 (0xc000)

partition size: 204800 (0x32000)

text section offset: 0 (0x0)

=== signed binaries:

bin: /home/antonio/ncs/build/zephyr/zephyr.signed.bin

Usage: imgtool sign [OPTIONS] INFILE OUTFILE

Error: Invalid value for "-H" / "--header-size": Minimum value for -H/--header-size is 32

FATAL ERROR: command exited with status 2: /home/antonio/.local/bin/imgtool sign --version 0.0.0+0 --align 4 --header-size 0 --slot-size 204800 --key bootloader/mcuboot/root-rsa-2048.pem /home/antonio/ncs/build/zephyr/zephyr.bin /home/antonio/ncs/build/zephyr/zephyr.signed.bin

  • Thanks Einar.

    Actually my question was not about how to detect the OS, but rather that setting the CONFIG_BOOT_SIGNATURE_KEY_FILE in CMakeLists did not work, as I highlighted in yellow, and even if it did, I would still need to find a way to set it for the mcuboot build, outside mcuboot.conf, which will not let me do conditionals to detect the OS.

    Please advice.

  • Hi Antonio,

    I see.

    There are some issues with your Cmake code. ${CMAKE_CURRENT_SOURCE_DIR} gives you the absolute path, so it makes no sense to prefix it with ../../../. A possible way to solve this is to slightly adjust the suggestion from here and use something like this:

    if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/mcuboot.conf")
      set(mcuboot_CONF_FILE prj.conf ${CMAKE_CURRENT_LIST_DIR}/mcuboot.conf)
      set(CONFIG_BOOT_SIGNATURE_KEY_FILE "${CMAKE_CURRENT_LIST_DIR}/../../../psl-rsa-2048.pem")

    But then you need to have both the mcuboot.conf and key file at the correct location. Also, this will only work if it comes before find_package(Zephyr).



  • Hi Einar,

    I did not think of that. My logic was that imgtool is being called from the ncs/bootloader/mcuboot location and it makes an assumption of going back from the zepyr env location and then forward, to where the default keys are, and from there I had to go back and into my own directory.

    The main problem is that KConfig in prj.conf has a default on CONFIG_BOOT_SIGNATURE_KEY_FILE which if it is not set there, iot places a default, overriding whatever you do in CMakeLists.

    And even when that is solved, there is still a problem with the key for mcuboot.conf.

    The whole thing is a mess, I hope something is figured out for portability sake.

    I have another question, is there a guide or a plan to be able to have the BLE controller separately in its own image, so only the app can be OTA?


  • Hi Antonio,

    Antonio said:
    The whole thing is a mess, I hope something is figured out for portability sake.

    It should be possible to do this more elegantly using a Zephyr module in the future. Then you can use _defconfig and point to a Zephyr module with your key (and code). That is not available in NCS 1.3.x, though.

    Antonio said:
    I have another question, is there a guide or a plan to be able to have the BLE controller separately in its own image, so only the app can be OTA?

    I do not see how. The controller is part of the application (for the nRF52 series / single CPU) so it is not easily separated. (This is fundamentally different from when using the nRF5 SDK and SoftDevice, as then the SoftDevice and application are built independently).


  • Thanks Einar,

    I see that it is somehow fixed in v1.4.0-rc2, but I am failing to make it work so far. It does not say if the mcuboot.conf is still needed.

    Also, and it has happened to me before, my modules that use the "u8_t" short typing start failing, they expect the normal "uint8_t". Do yo know if it is a header that I am missing?

    Also a comment. if you do in ubuntu in a terminal "git checkout v1.4.0-rc2" it fails to find it. You have to use a GUI git handler like VS Code or SmartGit to do the checkout.



    It does look like the key directories is fixed on the new 1.4.0 release.

    I failed to make smp_srv work though. I tested 1.4.0-rc2

    I did not have a problem signing with the new CONFIG_MCUBOOT_SIGNATURE_KEY_FILE, which is supposed to take care of both signings, and is no longer an extension of the absolute position of mcuboot dir, and now yo have to add CONFIG_MCUMGR_SMP_BT=y and CONFIG_MCUMGR_SMP_BT_AUTHEN=n since BLE is not a default now.

    I hope the is a guide (I did not find one), as the instructions to do BLE OTA changed, and this sample project is the only guide for that.

    I'll wait for the final release to test again.