Downgrade protection works only for the app_core -image-and not for the net-core -image

Hallo,

we are using the nrf5340 and the ncs Version 2.6.1.

I activated the software downgrade protection as described here Downgrade protection (nordicsemi.com)

Then I made some simultaneious FOTA updates (App-image + Net-image) by using the nRF Connect app with different versions.

What I see is that the downngrade protection works for the App-image. It is not possible to update an App-image V2.0.0. with an App-image V1.0.0.

But it is possible to downgrade the Net- image V2.0.0 with the Net-image V1.0.0

How can I activate the downgrade protection also for the net-core ?

 

Best regards,

Georg

Parents
  • Hi, 

    Do you test the MCUBoot version by adjusting CONFIG_MCUBOOT_HW_DOWNGRADE_PREVENTION_COUNTER_VALUE?

    How do you check the version number? You can check the version by 

    imgtool verify build/zephyr/net_core_app_update.bin

    Regards,
    Amanda H.

  • Hi,

    I checked the version information by looking into the header of the net_core_app update.bin file.  

    Here are the configuration switches which I have added to activate the downgrade prevention:

    CONFIG_BOOT_VERSION_CMP_USE_BUILD_NUMBER=y
    CONFIG_MCUBOOT_DOWNGRADE_PREVENTION=y

    In the build configuration I added:

    -DSB_CONFIG_MCUBOOT_MODE_OVERWRITE_ONLY=y

    And  there is also a VERSION file which looks like this:

    Some additional information:

    We are using a serial external flash to store the secondary images of the app-core and the net-core.

    After making an simultaineious update by using dfu_application.zip it seems that the header ifnormation of the net_core_app_update.bin is corrupt when lokking into the memory of the nrf5340-net-core. So there is no version information any more.

    When looking into the memory of the app-core the header information seems to be ok 

    Best regards,

    Georg

  • Hi, 

    Georg said:
    Is there a tool to read out the version of the current programmed app-/net-image in the nrf5340 ?

    You can read the image version with the nRF Device app or get the version number in the code.  

    Georg said:
    Now the nrf 5340 is programmed with the appV2 and netV1 images. This is the problem, the downgrade prevention works for the app-core but not for the net-core. The net-core was downgraded.

    How do you check the version on the netcore?

    -Amanda H.

  • Hi Amanda,

    thank you for your answer.

    When looking in the google play store I can't find the nRF Device app.

    There is a nRF Device Manager app but here I can't find the option to read out the version.

    Which app do you mean?

    To get different versions for the net-image I added a version string in the main program of the net-core-image like this:

    After updating the device I read out the memory of the nrf5340 (with the Programmer) and check the version string like this:

    What I found out during debugging is that the version of the net image get lost when MCUboot transfers the net-core-image from the secondary slot to the primary slot. The version information which is placed in the header of the net_core_app_update.bin image is not programmed into the net core (primary slot). MCUboot assumes that the version of the net-core-image is 0.0.0, this means that downgrade prevention doesn’t work.

    See the function boot_read_image_header_hook_in the file nrf_hooks.c

    int boot_read_image_header_hook_(int img_index, int slot, struct image_header *img_head)
    {
    	if (img_index == 1 && slot == 0) {
    		img_head->ih_magic = IMAGE_MAGIC;
    		img_head->ih_hdr_size = PM_MCUBOOT_PAD_SIZE;
    		img_head->ih_load_addr = PM_MCUBOOT_PRIMARY_1_ADDRESS;
    		img_head->ih_img_size = PM_CPUNET_APP_SIZE;
    		img_head->ih_flags = 0;
    		img_head->ih_ver.iv_major = 0;
    		img_head->ih_ver.iv_minor = 0;
    		img_head->ih_ver.iv_revision = 0;
    		img_head->ih_ver.iv_build_num = 0;
    		img_head->_pad1 = 0;
    		return 0;
    	}
    
    	return BOOT_HOOK_REGULAR;
    }
    

    Best regards,

    Georg


  • Hi, 

    Sorry, it's nRF Connect Device Manager

    Thanks for finding the root cause. I will report to the internal. 

    -Amanda H.

  • Hi just wanted to add that we just found the same issue so can confirm a reproducible offender. 

  • Hi,

    thank you.

    I hope you find a solution because we want to use this feature in our product.

    Best regards,

    Georg

Reply Children
  • Hi, 

    To enable the netcore downgrade protection use FW_INFO_FIRMWARE_VERSION and add the following kconfigs:

    mcuboot.conf under child_image folder:

    CONFIG_FW_INFO=y
    CONFIG_PCD_APP=y
    CONFIG_PCD_READ_NETCORE_APP_VERSION=y

    hci_ipc.conf under child_image folder:

    CONFIG_FW_INFO_FIRMWARE_VERSION=2


    b0n.conf under child_image folder:
    CONFIG_PCD_READ_NETCORE_APP_VERSION=y

    -Amanda H.

  • Hi Amanda,

    thank you for your answer and sorry for my late reply.

    Up to now I didn't a have file b0n.conf . So I created this file with only this entry. 

    CONFIG_PCD_READ_NETCORE_APP_VERSION=y

    I tried your solution but get some errors during build.

    -- west build: generating a build system
    Loading Zephyr default modules (Zephyr base).
    -- Application: C:/Projekte/BleCan_CAB11A
    -- CMake version: 3.21.0
    -- Found Python3: C:/ncs/toolchains/cf2149caf2/opt/bin/python.exe (found suitable version "3.9.13", minimum required is "3.8") found components: Interpreter
    -- Cache files will be written to: C:/DevTools/ncs/v2.6.1/zephyr/.cache
    -- Zephyr version: 3.5.99 (C:/DevTools/ncs/v2.6.1/zephyr)
    CMake Error at C:/DevTools/ncs/v2.6.1/zephyr/cmake/modules/version.cmake:76 (math):
    math cannot parse the expression: "(2 << 16) + ( << 8) + (0)": syntax
    error, unexpected exp_SHIFTLEFT (16).
    Call Stack (most recent call first):
    C:/DevTools/ncs/v2.6.1/zephyr/cmake/modules/zephyr_default.cmake:129 (include)
    C:/DevTools/ncs/v2.6.1/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)
    C:/DevTools/ncs/v2.6.1/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
    CMakeLists.txt:14 (find_package)


    CMake Error at C:/DevTools/ncs/v2.6.1/zephyr/cmake/modules/version.cmake:77 (math):
    math cannot parse the expression: "(2 << 24) + ( << 16) + (0 << 8) +
    (2408081002)": syntax error, unexpected exp_SHIFTLEFT (16).
    Call Stack (most recent call first):
    C:/DevTools/ncs/v2.6.1/zephyr/cmake/modules/zephyr_default.cmake:129 (include)
    C:/DevTools/ncs/v2.6.1/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)
    C:/DevTools/ncs/v2.6.1/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
    CMakeLists.txt:14 (find_package)

    Best regards,

    Georg

    • Hi,

      the problem with the error is solved.

      After flashing the software with the additional config switches, our software doesn't boot any more

      It seems that the software hangs in the bootoloader.

       

      Rest regards,

      Georg

  • Hi, 

    the program hangs  in the "do while" loop  of the function: network_core_pcd_cmdset in the file pcd.c

    The command_status is PCD_STATUS_READ_VERSION

    tatic int network_core_pcd_cmdset(uint32_t cmd, const void *src_addr, size_t len, bool wait)
    {
    	int err;
    	enum pcd_status command_status;
    
    	/* Ensure that the network core is turned off */
    	nrf_reset_network_force_off(NRF_RESET, true);
    
    	err = pcd_cmd_write(cmd, src_addr, len, PCD_NET_CORE_APP_OFFSET);
    	if (err != 0) {
    		LOG_INF("Error while writing PCD cmd: %d", err);
    		return err;
    	}
    
    	enum pcd_status initial_command_status = pcd_fw_copy_status_get();
    
    	nrf_reset_network_force_off(NRF_RESET, false);
    	LOG_INF("Turned on network core");
    
    	if (!wait) {
    		return 0;
    	}
    
    	do {
    		/* Wait for 1 second to avoid issue where network core
    		 * is unable to write to shared RAM.
    		 */
    		k_busy_wait(1 * USEC_PER_SEC);
    
    		command_status = pcd_fw_copy_status_get();
    	} while (command_status == initial_command_status);
    

    Best regards,

    Georg

Related