How to reject old firmware version from AWS FOTA at NRF9160 side?

Hi Nordic team

Customer Delta was running a street lamp project.

For AWS FOTA, they applied a AWS account and firmware update already can work.

However, it looks like no version control ability. No matter new or old firmware from AWS,

NRF9160 accepted both.

How can we make it at NRF9160 side? Let NRF9160 reject older version update.

This project was from SDK Connect v1.3.0 http_application_update.

Jeffery

Parents
  • Hi Simon

    1. I tried sdk connect v1.8.0 application update example. Added configuration settings to prevent downgrade.

       However, it popped error as the project was opened. Anything wrong?

    2. The project customer referred to was v1.3.0. So, does it support mcuboot preventing downgrade?

    Jeffery

  • I tested this myself, and it seems like there is some bugs with the OVERLAY_CONFIG functionality. I will report internally as a bug*

    Instead I added the MCUBoot configs in the CMakeListst.txt like this:

    set(mcuboot_CONFIG_MCUBOOT_DOWNGRADE_PREVENTION
        y
    )
    set(mcuboot_CONFIG_BOOT_UPGRADE_ONLY
        y
    )
    

    Could you test the following sample with NCS v1.8.0:

    mcuboot_prevent_downgrade.zip

    • Build it using the board nrf9160dk_nrf9160_ns
    • You should get the following output:

    ...
    ...
    ...
    29 NRF_PDM              Non-Secure      OK
    30 NRF_I2S              Non-Secure      OK
    31 NRF_GPIOTE1          Non-Secure      OK
    
    SPM: NS image at 0x20200
    SPM: NS MSP at 0x200154d0
    SPM: NS reset vector at 0x216cd
    SPM: prepare to jump to Non-Secure image.
    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    MCUBOOT IMAGE VERSION: 1.0.0
    Hello World! nrf9160dk_nrf9160

    • Next, change CONFIG_MCUBOOT_IMAGE_VERSION to "0.0.0" in mcuboot_prevent_downgrade/prj.conf
    • Build the sample again (pristine) without flashing it
      • Make sure CONFIG_MCUBOOT_IMAGE_VERSION is "0.0.0" in <sample>/build/zephyr/.config
    • Open the command line in ../mcuboot_prevent_downgrade/build/zephyr and run the following command:

    nrfjprog --program app_moved_test_update.hex

    Read more about the file app_moved_test_update.hex in the MCUBoot documentation

    • Reset the nRF9160 DK and you should see the following output:

    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    I: Starting bootloader
    I: Swap type: test
    E: insufficient version in secondary slot
    I: Bootloader chainload address offset: 0x10000
    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    Flash regions           Domain          Permissions
    00 03 0x00000 0x20000   Secure          rwxl
    ...
    ...
    ...
    SPM: prepare to jump to Non-Secure image.
    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    MCUBOOT IMAGE VERSION: 1.0.0
    Hello World! nrf9160dk_nrf9160

    Report back to me if this works for you or not

    Best regards,

    Simon


    *I had to enable these in mcuboot.conf, then "Unable to find bootable image.." went away

    CONFIG_PARTITION_MANAGER_ENABLED=y
    CONFIG_FLASH_MAP_CUSTOM=y

    Then I added the below configs to mcuboot.conf as well, but they were not propogated to the file <sample>/build/mcuboot/zephyr/.config

    CONFIG_MCUBOOT_DOWNGRADE_PREVENTION=y
    CONFIG_BOOT_UPGRADE_ONLY=y

    I will report this internally and get back to you in this ticket when we find a solution

  • Hi Simon

    1.

    Added the MCUBoot configs in the CMakeListst.tx of sdk v1.8.0 application_update, preventing downgrade did work.

    set(mcuboot_CONFIG_MCUBOOT_DOWNGRADE_PREVENTION
    y
    )
    set(mcuboot_CONFIG_BOOT_UPGRADE_ONLY
    y
    )

    2.

    However, my project was based on sdk connect v1.3.0 http_application_update.

    When I tried FOTA, it can download new app_update.bin from your AWS "nrfconnectsdk.s3.eu-central-

    1.amazonaws.com". But, swap failed. Log show error and secondary image was invalid.

    Jeffery

  • I just tested the sample mcuboot_prevent_downgrade I uploaded in my last reply with NCS v1.3.0, with the following addition in CMakeLists.txt

    set(mcuboot_CONFIG_BOOT_SWAP_USING_MOVE n)

     I followed the same instructions as in my last reply and I got this output

    ** Booting Zephyr OS build v2.3.0-rc1-ncs1  ***
    [00:00:00.003,540] <inf> mcuboot: Starting bootloader
    [00:00:00.009,613] <inf> mcuboot: Swap type: test
    [00:00:00.014,801] <err> mcuboot: insufficient version in secondary slot
    [00:00:09.301,605] <inf> mcuboot: Bootloader chainload address offset: 0x10000
    [00:00:09.309,387] <inf> mcuboot: Jumping to the first image slot
    *** Booting Zephyr OS build v2.3.0-rc1-ncs1  ***
    Flash regions           Domain          Permissions
    00 02 0x00000 0x18000   Secure          rwxl
    03 31 0x18000 0x100000  Non-Secure      rwxl
    
    Non-secure callable region 0 placed in flash region 2 with size 32.
    
    SRAM region             Domain          Permissions
    00 07 0x00000 0x10000   Secure          rwxl
    08 31 0x10000 0x40000   Non-Secure      rwxl
    
    Peripheral              Domain          Status
    00 NRF_P0               Non-Secure      OK
    01 NRF_CLOCK            Non-Secure      OK
    02 NRF_RTC0             Non-Secure      OK
    03 NRF_RTC1             Non-Secure      OK
    04 NRF_NVMC             Non-Secure      OK
    05 NRF_UARTE1           Non-Secure      OK
    06 NRF_UARTE2           Secure          SKIP
    07 NRF_TWIM2            Non-Secure      OK
    08 NRF_SPIM3            Non-Secure      OK
    09 NRF_TIMER0           Non-Secure      OK
    10 NRF_TIMER1           Non-Secure      OK
    11 NRF_TIMER2           Non-Secure      OK
    12 NRF_SAADC            Non-Secure      OK
    13 NRF_PWM0             Non-Secure      OK
    14 NRF_PWM1             Non-Secure      OK
    15 NRF_PWM2             Non-Secure      OK
    16 NRF_PWM3             Non-Secure      OK
    17 NRF_WDT              Non-Secure      OK
    18 NRF_IPC              Non-Secure      OK
    19 NRF_VMC              Non-Secure      OK
    20 NRF_FPU              Non-Secure      OK
    21 NRF_EGU1             Non-Secure      OK
    22 NRF_EGU2             Non-Secure      OK
    23 NRF_DPPIC            Non-Secure      OK
    24 NRF_GPIOTE1          Non-Secure      OK
    25 NRF_REGULATORS       Non-Secure      OK
    
    SPM: NS image at 0x1c200
    SPM: NS MSP at 0x20020620
    SPM: NS reset vector at 0x1d151
    SPM: prepare to jump to Non-Secure image.
    *** Booting Zephyr OS build v2.3.0-rc1-ncs1  ***
    MCUBOOT IMAGE VERSION: 1.0.0
    Hello World! nrf9160dk_nrf9160

    So the downgrade prevention should work fine in NCS v1.3.0. 

    I guess the issue is with the file app_update.bin from your AWS "nrfconnectsdk.s3.eu-central-1.amazonaws.com". 

    How do you know what version app_update.bin using, and that it is less than 1.0.0?

    Please create a new app_update.bin  (should be generated into <application>/build/zephyr/app_update.binwith CONFIG_MCUBOOT_IMAGE_VERSION="0.0.0" and upload it to <your cloud server>, then try again.

  • Hi Simon

    Thanks for your support. Now, preventing downgrade for AWS FOTA can work at v1.3.0 example.

    By the way, we know CONFIG_MCUBOOT_IMAGE_VERSION string is formatted as "A.B.C+D".

    What is maximum value for each digit (A, B, C and D)? Only from 0 to 9?

    I cannot find the information at google serach.

    Jeff

  • This is the struct used to store the image version (bootloader/mcuboot/boot/bootutil/include/bootutil/image.h):

    struct image_version {
        uint8_t iv_major;
        uint8_t iv_minor;
        uint16_t iv_revision;
        uint32_t iv_build_num;
    };
    

    The format is the following: maj.min.rev+build

    As you can see the major and minor fields are 1 byte long and can store numbers as large as 255. For the revision field (2 byte), the largest number you can store is 65536 and for build_num (4 bytes), the largest number you can store is 2^32.

    Be aware that I have not done any tests using large numbers, so you may want to test yourself first to be certain.

Reply
  • This is the struct used to store the image version (bootloader/mcuboot/boot/bootutil/include/bootutil/image.h):

    struct image_version {
        uint8_t iv_major;
        uint8_t iv_minor;
        uint16_t iv_revision;
        uint32_t iv_build_num;
    };
    

    The format is the following: maj.min.rev+build

    As you can see the major and minor fields are 1 byte long and can store numbers as large as 255. For the revision field (2 byte), the largest number you can store is 65536 and for build_num (4 bytes), the largest number you can store is 2^32.

    Be aware that I have not done any tests using large numbers, so you may want to test yourself first to be certain.

Children
No Data
Related