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 \

   -- \

   -DOVERLAY_CONFIG=overlay-bt.conf

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

  • Hi,

    You do not need to sign the binaries "manually", as this is handled automatically for you by the partition manager when building with CONFIG_BOOTLOADER_MCUBOOT. The only thing you need to do is to set CONFIG_BOOT_SIGNATURE_KEY_FILE in the configuration for mcuboot as explained here, or by adding a separate config file as explained here.

    Update: Changed to CONFIG_BOOT_SIGNATURE_KEY_FILE as this post previously incorrectly referred to CONFIG_MCUBOOT_SIGNATURE_KEY_FILE, which is not used by the partition manager.

  • Hi Einor,

    Thanks for your advice. It worked! I am trying to understand all of the inner workings because I do not like to deal with black boxes when the project start getting complex.

    I still had a problem trying to have the key out of box.

    This is what I did:

    Moved smp_srv to ˜/Documents

    Created a key in smp_srv

    imgtool keygen -k psl-2048.pem -t rsa-2048

    Added to CMakeLists.txt

    if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.conf")

      set(mcuboot_CONF_FILE

        prj.conf

        ${CMAKE_CURRENT_LIST_DIR}/mcuboot.conf

      )

    endif()

    And a mcuboot.conf file with:

    CONFIG_BOOT_SIGNATURE_KEY_FILE="psl-rsa-2048.pem"

    As well as add it to the prj.conf

    The result was the following, at build time:

    Combining 'modules/mcuboot/mcuboot_subimage-prefix/src/mcuboot_subimage-stamp/mcuboot_subimage-patch'

    Building 'modules/mcuboot/mcuboot_subimage-prefix/src/mcuboot_subimage-stamp/mcuboot_subimage-configure' from solution 'build' in configuration 'Common'

      Combining 'modules/mcuboot/mcuboot_subimage-prefix/src/mcuboot_subimage-stamp/mcuboot_subimage-configure'

    Building 'mcuboot/zephyr/zephyr.hex' from solution 'build' in configuration 'Common'

      Combining 'mcuboot/zephyr/zephyr.hex'

        '/home/antonio/ncs/bootloader/mcuboot/psl-rsa-2048.pem', needed by 'zephyr/autogen-pubkey.c', missing and no known rule to make it

    Build failed

    So I moved the key to /ncs/bootloader/mcuboot and it worked

    How can I have the key out-of-tree in my project or some other directory?

    Thanks!

  • Hi,

    The CONFIG_BOOT_SIGNATURE_KEY_FILE is relative to the mcuboot folder, and I do not see any way to make it relative to another location (like your application). You can use an absolute path, though. See this post for more information.

  • Thank you Einar. It worked!!

    It is not exactly clean though, because it sets statically both where the project has to be placed in everyone's computer that is working on the project as well as the OS (linux in my case).

    Also, I had to do two different paths:

    For mcuboot.conf: 

    CONFIG_BOOT_SIGNATURE_KEY_FILE="~/Documents/tests/smp_svr/psl-rsa-2048.pem"

    And for prj.conf(for signing my own app):

    CONFIG_BOOT_SIGNATURE_KEY_FILE="../../../Documents/tests/smp_svr/psl-rsa-2048.pem"

    I tried to do it on CMakelists for the project I could pass along the ${CMAKE_CURRENT_SOURCE_DIR} and set the flag for my own project with something like:

    if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.conf")

        set(mcuboot_CONF_FILE prj.conf ${CMAKE_CURRENT_LIST_DIR}/mcuboot.conf)

        set(CONFIG_BOOT_SIGNATURE_KEY_FILE "../../../${CMAKE_CURRENT_SOURCE_DIR}/psl-rsa-2048.pem")

    endif()

    but the setting of the flag did not work, and i still had the problem of how to do the same for the flag that has to be set for the mcuboot building.

    Would you know how to do this from CMakeLists, so at least I can make it more portable, by detecting the OS in an if()?

    Thanks!

  • Hi,

    I am not a Cmake wizard, but it shoul be possible to check the platform varibles as suggested in this stack overflow post to differenciate paths between plaforms.

Related