This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Undefined reference to rsa_pub_key when CONFIG_BOOT_SIGNATURE_KEY_FILE is defined

Hello,

I would like to sign a firmware image with a custom private key. This is intended for OTA firmware update. The key type is ecdsa-p256 and the file containing the key is named ecdsa-dev.pem. The SDK is nRF Connect SDK 1.6.0.

To illustrate the issue, I took the hello_world example and modified it like described below.

In CMakeLists.txt, I set a value for mcuboot_CONFIG_BOOT_SIGNATURE_KEY_FILE as follows:

cmake_minimum_required(VERSION 3.13.1)
set(mcuboot_CONFIG_BOOT_SIGNATURE_KEY_FILE "\"${CMAKE_CURRENT_LIST_DIR}/ecdsa-dev.pem\"")
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
[...]

(got idea from https://devzone.nordicsemi.com/f/nordic-q-a/67510/ncs-recommended-mcuboot-enabled-apps-build-and-flash-methods/324792#324792 )

In prj.conf, I enabled mcuboot as follows:

# Bootloader
CONFIG_BOOTLOADER_MCUBOOT=y

In the root of the project (beside CMakeLists.txt), I copied the private key file ecdsa-dev.pem.

Then, when I want to compile with the command west build -b nrf52833dk_nrf52833, I have errors related to undefined reference to `rsa_pub_key' and `rsa_pub_key_len' :

[5/158] Performing build step for 'mcuboot_subimage'
[243/250] Linking C executable zephyr\zephyr_prebuilt.elf
FAILED: zephyr/zephyr_prebuilt.elf zephyr/zephyr_prebuilt.map C:/Users/dev/ncs/v1.6.0/zephyr/samples/hello_world-mcuboot/build/mcuboot/zephyr/zephyr_prebuilt.map 
cmd.exe /C "cd . && C:\gnuarmemb\bin\arm-none-eabi-gcc.exe   zephyr/CMakeFiles/zephyr_prebuilt.dir/misc/empty_file.c.obj -o zephyr\zephyr_prebuilt.elf  zephyr/CMakeFiles/offsets.dir/./arch/arm/core/offsets/offsets.c.obj  -Wl,-T  zephyr/linker_zephyr_prebuilt.cmd  -Wl,-Map=C:/Users/dev/ncs/v1.6.0/zephyr/samples/hello_world-mcuboot/build/mcuboot/zephyr/zephyr_prebuilt.map  -Wl,--whole-archive  app/libapp.a  zephyr/libzephyr.a  zephyr/arch/common/libarch__common.a  zephyr/arch/arch/arm/core/aarch32/libarch__arm__core__aarch32.a  zephyr/arch/arch/arm/core/aarch32/cortex_m/libarch__arm__core__aarch32__cortex_m.a  zephyr/arch/arch/arm/core/aarch32/mpu/libarch__arm__core__aarch32__mpu.a  zephyr/lib/libc/minimal/liblib__libc__minimal.a  zephyr/lib/posix/liblib__posix.a  zephyr/soc/arm/common/cortex_m/libsoc__arm__common__cortex_m.a  zephyr/soc/arm/nordic_nrf/nrf52/libsoc__arm__nordic_nrf__nrf52.a  zephyr/drivers/gpio/libdrivers__gpio.a  zephyr/drivers/flash/libdrivers__flash.a  zephyr/drivers/serial/libdrivers__serial.a  modules/nrf/lib/fprotect/lib..__nrf__lib__fprotect.a  modules/nrf/lib/fatal_error/lib..__nrf__lib__fatal_error.a  modules/mcuboot/boot/bootutil/zephyr/libmcuboot_util.a  modules/hal_nordic/nrfx/libmodules__hal_nordic__nrfx.a  modules/mbedtls/libmodules__mbedtls.a  modules/segger/libmodules__segger.a  -Wl,--no-whole-archive  zephyr/kernel/libkernel.a  -L"c:/gnuarmemb/bin/../lib/gcc/arm-none-eabi/10.2.1/thumb/v7e-m/nofp"  -LC:/Users/dev/ncs/v1.6.0/zephyr/samples/hello_world-mcuboot/build/mcuboot/zephyr  -lgcc  zephyr/arch/common/libisr_tables.a  -mcpu=cortex-m4  -mthumb  -mabi=aapcs  -Wl,--gc-sections  -Wl,--build-id=none  -Wl,--sort-common=descending  -Wl,--sort-section=alignment  -Wl,-u,_OffsetAbsSyms  -Wl,-u,_ConfigAbsSyms  -nostdlib  -static  -no-pie  -Wl,-X  -Wl,-N  -Wl,--orphan-handling=warn && cmd.exe /C "cd /D C:\Users\dev\ncs\v1.6.0\zephyr\samples\hello_world-mcuboot\build\mcuboot\zephyr && "C:\Program Files\CMake\bin\cmake.exe" -E echo ""
c:/gnuarmemb/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(keys.c.obj):C:/Users/dev/ncs/v1.6.0/bootloader/mcuboot/boot/zephyr/keys.c:52: undefined reference to `rsa_pub_key'
c:/gnuarmemb/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(keys.c.obj):(.rodata.bootutil_keys+0x4): undefined reference to `rsa_pub_key_len' 
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Instead of setting mcuboot_CONFIG_BOOT_SIGNATURE_KEY_FILE in the app's CMakeLists.txt, i tried to set it directly in the prj.conf file of mcuboot in bootloader\mcuboot\boot\zephyr (by adding CONFIG_BOOT_SIGNATURE_KEY_FILE="C:\\ota\\ecdsa-dev.pem" for example), but exactly the same error occurs at compile time.

The fact that the error itself is related to a RSA key is a first issue since the custom private key is for ECDSA.

The compilation succeeds in the following cases:

  • Either use a custom .pem file containing a rsa-2048 key instead of a ecdsa-p256 key.
  • Or compile for the target the nRF52840 DK, using the command west build -b nrf52840dk_nrf52840

As a consequence, I think that this compilation error might be related to the fact that the nRF52833 embeds less cryptographic hardware compared to the nRF52840, such as the Cryptocell.

Is there a way to use the ecdsa-p256 algorithm with the nRF52833 nevertheless ?

Parents
  • Hi, 

    I will look in to this and try to provide a answer shortly. 

    Regards,
    Jonathan

  • Hello,

    I managed to get the project compile for the nRF52833 by enabling MCUBoot's CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 option.

    To do this, I added the following line to the CMakeLists.txt file of the application project, before  find_package():

    set(mcuboot_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 y)

    Do you think this is sufficient to get the nRF52833 verify ECDSA signatures?

  • Hi,

    Using Kconfigs by create a folder called "child_image" in the sample directory and place the Kconfig configurations in a file called "mcuboot.conf".
    With the following Kconfig options:
    CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y
    CONFIG_BOOT_SIGNATURE_KEY_FILE="nameoffile.pem"

    Should also work. 

    Anthony said:
    Do you think this is sufficient to get the nRF52833 verify ECDSA signatures?

    I will double check this and get back to you. 

    Regards,
    Jonathan

  • Yes, the method is ok.

    There is a more documentation here for the  "child_image" folder as suggest in previous reply. And for setting the properties here is the description. 

    Regards,
    Jonathan

  • Hello Jonathan,

    Thank you for your answer. It works. I had to use a variant of your proposal in order to be able to refer to the .pem file located in the app project without specifiying its absolute path.

    Indeed, when setting the mcuboot-specific configuration file in child_image/mcuboot.conf (or child_image/mcuboot/prj.conf to overwrite the whole configuration), our .pem coulnd't be found when giving a relative path. The reason is that relative paths are resolved for the mcuboot child image directory.

    As a workaround, I set the mcuboot configuration file in the app's CMakeLists.txt file :

    set(mcuboot_CONF_FILE "${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.conf")

    That way, CONFIG_BOOT_SIGNATURE_KEY_FILE can be given a relative path, which will be searched in the app's directory if not found in the mcuboot directory.

Reply
  • Hello Jonathan,

    Thank you for your answer. It works. I had to use a variant of your proposal in order to be able to refer to the .pem file located in the app project without specifiying its absolute path.

    Indeed, when setting the mcuboot-specific configuration file in child_image/mcuboot.conf (or child_image/mcuboot/prj.conf to overwrite the whole configuration), our .pem coulnd't be found when giving a relative path. The reason is that relative paths are resolved for the mcuboot child image directory.

    As a workaround, I set the mcuboot configuration file in the app's CMakeLists.txt file :

    set(mcuboot_CONF_FILE "${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.conf")

    That way, CONFIG_BOOT_SIGNATURE_KEY_FILE can be given a relative path, which will be searched in the app's directory if not found in the mcuboot directory.

Children
No Data
Related