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

How to specify signing the key with MCUBoot

Hello,

I am using NCS v1.5.0 and an nRF9160 on a custom board, my application has a custom SPM and the secondary slot for the firmware image upgrade is stored on an external flash.

I generated a private key, and I am passing it to the MCUBoot as CONFIG_BOOT_SIGNATURE_KEY_FILE="C:/workspace/repos/DNG/keys/development_private.pem". This key appears to be used because I see during the build process:

=== child image mcuboot - begin ===
Including boilerplate (Zephyr base): C:/Nordic/v1.5.0/zephyr/cmake/app/boilerplate.cmake
-- Application: C:/Nordic/v1.5.0/bootloader/mcuboot/boot/zephyr
-- Using NCS Toolchain 1.5.0 for building. (C:/Nordic/v1.5.0/toolchain/cmake)
-- Zephyr version: 2.4.99 (C:/Nordic/v1.5.0/zephyr)
-- Found Python3: C:/Nordic/v1.5.0/toolchain/opt/bin/python.exe (found suitable exact version "3.8.2") found components: Interpreter
-- Found west (found suitable version "0.9.0", minimum required is "0.7.1")
-- Board: dng_nrf9160
-- Cache files will be written to: C:/Nordic/v1.5.0/zephyr/.cache
-- Found dtc: C:/Nordic/v1.5.0/toolchain/opt/bin/dtc.exe (found suitable version "1.4.7", minimum required is "1.4.6")
-- Found toolchain: gnuarmemb (C:/Nordic/v1.5.0/toolchain/opt)
-- Found BOARD.dts: C:/workspace/repos/DNG/boards/arm/dng_nrf9160/dng_nrf9160.dts
-- Found devicetree overlay: C:/Nordic/v1.5.0/bootloader/mcuboot/boot/zephyr/dts.overlay
-- Generated zephyr.dts: C:/workspace/repos/DNG/build/mcuboot/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: C:/workspace/repos/DNG/build/mcuboot/zephyr/include/generated/devicetree_unfixed.h
-- Generated device_extern.h: C:/workspace/repos/DNG/build/mcuboot/zephyr/include/generated/device_extern.h
Parsing C:/Nordic/v1.5.0/bootloader/mcuboot/boot/zephyr/Kconfig
Loaded configuration 'C:/workspace/repos/DNG/boards/arm/dng_nrf9160/dng_nrf9160_defconfig'
Merged configuration 'C:/Nordic/v1.5.0/bootloader/mcuboot/boot/zephyr/prj.conf'
Merged configuration 'C:/workspace/repos/DNG/mcuboot.conf'
Configuration saved to 'C:/workspace/repos/DNG/build/mcuboot/zephyr/.config'
Kconfig header saved to 'C:/workspace/repos/DNG/build/mcuboot/zephyr/include/generated/autoconf.h'
-- The C compiler identification is GNU 9.2.1
-- The CXX compiler identification is GNU 9.2.1
-- The ASM compiler identification is GNU
-- Found assembler: C:/Nordic/v1.5.0/toolchain/opt/bin/arm-none-eabi-gcc.exe
MCUBoot bootloader key file: C:/workspace/repos/DNG/keys/development_private.pem
-- Configuring done
-- Generating done
-- Build files have been written to: C:/workspace/repos/DNG/build/mcuboot
=== child image mcuboot - end ===

The problem is that on startup, MCUBoot complains that it cannot find the image:


*** Booting Zephyr OS build v2.4.99-ncs1 ***
[00:00:00.380,249] <inf> mcuboot: Starting bootloader
[00:00:00.380,920] <wrn> mcuboot: Failed reading sectors; BOOT_MAX_IMG_SECTORS=256 - too small?
[00:00:00.380,981] <err> mcuboot: Image in the primary slot is not valid!
[00:00:00.380,981] <err> mcuboot: Unable to find bootable image

I suspect this is related to the signing keys used, but I cannot understand why or where the problem is occuring. 

I tried adding CONFIG_BOOT_SIGNATURE_KEY_FILE="C:/workspace/repos/DNG/keys/development_private.pem" to the application prj.conf, but got this warning:

warning: BOOT_SIGNATURE_KEY_FILE (defined at C:/Nordic/v1.5.0/nrf\modules\Kconfig.mcuboot:10) was
assigned the value 'C:/workspace/repos/DNG/keys/development_private.pem' but got the value ''. Check
these unsatisfied dependencies: (!MCUBOOT_BUILD_STRATEGY_FROM_SOURCE) (=n). See
docs.zephyrproject.org/.../CONFIG_BOOT_SIGNATURE_KEY_FILE.html and/or
look up BOOT_SIGNATURE_KEY_FILE in the menuconfig/guiconfig interface. The Application Development
Primer, Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual
might be helpful too.

The project configurations and options are in this zip file: 8081.project.zip

My understanding is that the build system is given the private key (through the option CONFIG_BOOT_SIGNATURE_KEY_FILE) and then:

1. the MCUBoot build process generates the *public key*, converts it to a C array and it gets hardcoded in the bootloader firmware

2. the application build system uses the *private key* to sign the image using the image tool

3. finally, the bootloader and the signed application (my application + custom SPM) are merged into a single hex file

4. the command "west flash" flashes the combined bootloader + app hex

Is this correct ? If so, how can I specify the private key to the build process of MCUBoot and my application ?

I found similar issues in this link and also this one, but the anwsers were not clear to me.

Parents
  • Hakon,

    Thanks again for your help. I got everything up and running.

    I will take the opportunity to ask another question:

    In my application, the new firmware image is first transfered (through a proprietary protocol) to the device. And the upgrade only occurs if the user has requested it. With MCUBoot, will it try to update the firmware image as soon as it sees a valid new image in the secondary slot ? 

    Is there a library for controlling the firmware update process ? I only could find the DFU library, but it appears to be specific for the modem firmware, not the user application.

Reply
  • Hakon,

    Thanks again for your help. I got everything up and running.

    I will take the opportunity to ask another question:

    In my application, the new firmware image is first transfered (through a proprietary protocol) to the device. And the upgrade only occurs if the user has requested it. With MCUBoot, will it try to update the firmware image as soon as it sees a valid new image in the secondary slot ? 

    Is there a library for controlling the firmware update process ? I only could find the DFU library, but it appears to be specific for the modem firmware, not the user application.

Children
Related