From 195145ba45afb3a7295cfb8a186a141a1520c2f3 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Tue, 10 Oct 2023 15:51:54 +0200 Subject: [PATCH 001/238] [nrf noup] github: Add a commit tags check workflow Use the generic commit-tags action to provide sauce tag checks. Signed-off-by: Carles Cufi (cherry picked from commit 786e351400566f69289eace77f215a6376b851d9) --- .github/workflows/commit-tags.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/commit-tags.yml diff --git a/.github/workflows/commit-tags.yml b/.github/workflows/commit-tags.yml new file mode 100644 index 000000000..9e0323f94 --- /dev/null +++ b/.github/workflows/commit-tags.yml @@ -0,0 +1,31 @@ +name: Commit tags + +on: pull_request + +jobs: + commit_tags: + runs-on: ubuntu-22.04 + name: Run commit tags checks on patch series (PR) + steps: + - name: Update PATH for west + run: | + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Checkout the code + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Install python dependencies + run: | + pip3 install setuptools + pip3 install wheel + pip3 install gitlint + + - name: Run the commit tags + uses: nrfconnect/action-commit-tags@main + with: + target: '.' + baserev: origin/${{ github.base_ref }} + revrange: 'none' From 312ba86aa87e95563635536332e704d30c750a95 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Tue, 26 Mar 2019 15:42:38 +0100 Subject: [PATCH 002/238] [nrf noup] zephyr: Remove duplication from cmake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the `add_subdirectory` of nrfxlib it will still check that the nrfxlib is located outside the mcuboot directory. Signed-off-by: Sigvart Hovland Signed-off-by: Andrzej Puzdrowski Signed-off-by: Martí Bolívar Signed-off-by: Emil Obalski Signed-off-by: Andrzej Puzdrowski Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 5c94965afb7c8f8d1866ce2079e72f80bc889d1a) --- boot/zephyr/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 45548e0c3..92999a687 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -42,8 +42,6 @@ if(NOT EXISTS ${NRFXLIB_DIR}) To use the tinycrypt set `CONFIG_BOOT_ECDSA_TINYCRYPT` to y. ------------------------------------------------------------------------") endif() -# Don't include this if we are using west - add_subdirectory(${NRFXLIB_DIR} ${PROJECT_BINARY_DIR}/nrfxlib) endif() zephyr_library_include_directories( From cd1c995a5d48d182747449ad5cad16ae3c981f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 3 Sep 2021 14:38:54 -0700 Subject: [PATCH 003/238] [nrf noup] zephyr: add 'minimal' configuration files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add prj_minimal.conf, a Kconfig fragment to be used for minimally sized image production. The minimal fragment has been simplified for only external crypto. Move partition sizing into Kconfig to be consistent with the method used by b0. Using this fragment with prj_minimal.conf makes MCUboot < 16kB for all nRF devices (9160 still needs 32kB partition). Ref: NCSDK-6704 Signed-off-by: Stephen Stauts Signed-off-by: Martí Bolívar Signed-off-by: Sebastian Bøe Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 64740f7c95ca8b7b090086077876670edb95716b) --- .../nrf5340dk_nrf5340_cpuapp_minimal.conf | 13 ++++++ boot/zephyr/prj_minimal.conf | 41 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf create mode 100644 boot/zephyr/prj_minimal.conf diff --git a/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf b/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf new file mode 100644 index 000000000..dd5468106 --- /dev/null +++ b/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf @@ -0,0 +1,13 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# CC3xx is currently not used for nrf53 +CONFIG_HW_CC3XX=n +CONFIG_NRF_CC3XX_PLATFORM=n + +# Required for kernel operation +CONFIG_CLOCK_CONTROL=y +CONFIG_SYS_CLOCK_EXISTS=y diff --git a/boot/zephyr/prj_minimal.conf b/boot/zephyr/prj_minimal.conf new file mode 100644 index 000000000..1f90e708b --- /dev/null +++ b/boot/zephyr/prj_minimal.conf @@ -0,0 +1,41 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +CONFIG_MAIN_STACK_SIZE=10240 +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +CONFIG_FLASH=y +CONFIG_FPROTECT=y +CONFIG_PM=n + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_ENCRYPT_IMAGE=n + +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_BOOT_UPGRADE_ONLY=n + +### Minimal Configurations ### +CONFIG_BOOT_USE_MIN_PARTITION_SIZE=y +CONFIG_ASSERT=n +CONFIG_BOOT_BANNER=n +CONFIG_CLOCK_CONTROL=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_GPIO=n +CONFIG_KERNEL_MEM_POOL=n +CONFIG_LOG=n +CONFIG_MINIMAL_LIBC_CALLOC=n +CONFIG_MINIMAL_LIBC_MALLOC=n +CONFIG_MINIMAL_LIBC_REALLOCARRAY=n +CONFIG_NCS_SAMPLES_DEFAULTS=n +CONFIG_NO_RUNTIME_CHECKS=y +CONFIG_NRF_RTC_TIMER=n +CONFIG_PRINTK=n +CONFIG_SECURE_BOOT_DEBUG=n +CONFIG_SERIAL=n +CONFIG_SIZE_OPTIMIZATIONS=y +CONFIG_SYS_CLOCK_EXISTS=n +CONFIG_UART_CONSOLE=n From a53f78d7bde6697eb3eb938a993ad2970759d952 Mon Sep 17 00:00:00 2001 From: Bernt Johan Damslora Date: Fri, 20 Sep 2019 18:25:41 +0200 Subject: [PATCH 004/238] [nrf noup] boards: add support for Thingy:91 Adds project configurations for the two systems on the Thingy:91 (PCA-20035) board. The bootloader that is factory-programmed on thing91 does not support ECDSA signature type. Hence this commit also sets the signature type to RSA for applications built for Thingy:91. Signed-off-by: Bernt Johan Damslora Signed-off-by: Sigvart Hovland Signed-off-by: Jon Helge Nistad Signed-off-by: Balaji Srinivasan Signed-off-by: Robert Lubos Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Marek Pieta Signed-off-by: Dominik Ermel (cherry picked from commit de32681f8b9f6c27243a010752a9230662bf4db4) --- boot/zephyr/boards/thingy91_nrf52840.conf | 34 +++++++++++++++++++++++ boot/zephyr/boards/thingy91_nrf9160.conf | 13 +++++++++ 2 files changed, 47 insertions(+) create mode 100644 boot/zephyr/boards/thingy91_nrf52840.conf create mode 100644 boot/zephyr/boards/thingy91_nrf9160.conf diff --git a/boot/zephyr/boards/thingy91_nrf52840.conf b/boot/zephyr/boards/thingy91_nrf52840.conf new file mode 100644 index 000000000..c0d183401 --- /dev/null +++ b/boot/zephyr/boards/thingy91_nrf52840.conf @@ -0,0 +1,34 @@ +# Disable Zephyr console +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n + +# The build won't fit on the partition allocated for it without size +# optimizations. +CONFIG_SIZE_OPTIMIZATIONS=y +CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x12000 + +# Serial +CONFIG_SERIAL=y +CONFIG_UART_NRFX=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_LINE_CTRL=y + +# MCUboot serial recovery +CONFIG_GPIO=y +CONFIG_MCUBOOT_SERIAL=y +CONFIG_BOOT_SERIAL_CDC_ACM=y + +# Required by USB +CONFIG_MULTITHREADING=y + +# USB +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_PRODUCT="MCUBOOT" +CONFIG_USB_CDC_ACM=y +CONFIG_USB_COMPOSITE_DEVICE=y +CONFIG_USB_MASS_STORAGE=n +CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" +CONFIG_USB_DEVICE_VID=0x1915 +CONFIG_USB_DEVICE_PID=0x520F diff --git a/boot/zephyr/boards/thingy91_nrf9160.conf b/boot/zephyr/boards/thingy91_nrf9160.conf new file mode 100644 index 000000000..1bf2e424d --- /dev/null +++ b/boot/zephyr/boards/thingy91_nrf9160.conf @@ -0,0 +1,13 @@ +# Disable Zephyr console +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n + +# Disable Flash protection +CONFIG_FPROTECT=n + +# MCUBoot settings +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +# MCUboot serial recovery +CONFIG_MCUBOOT_SERIAL=y From 0faa8b2bb51bd58c9a1d3470f78f7b4136999652 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Thu, 14 Feb 2019 13:20:34 +0100 Subject: [PATCH 005/238] [nrf noup] boot: Add shared crypto for ECDSA and SHA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add functions for ecdsa_verify_secp256r1 and sha256 to use the shared crypto API * Add Kconfig and CMake variables for selecting shared crypto when using ecdsa * Add custom section to project for placing the API section in the correct location in flash * Add kconfig fragment for using external crypto Signed-off-by: Sigvart Hovland Signed-off-by: Martí Bolívar Signed-off-by: Emil Obalski Signed-off-by: Andrzej Puzdrowski Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Trond Einar Snekvik Signed-off-by: Georgios Vasilakis Signed-off-by: Johann Fischer Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 55683e3133b6a801a7bb7feb55d24be81ecccdbb) --- boot/bootutil/include/bootutil/crypto/ecdsa.h | 43 +++++++++++++++++++ boot/bootutil/include/bootutil/crypto/sha.h | 32 ++++++++++++++ boot/zephyr/CMakeLists.txt | 2 + boot/zephyr/external_crypto.conf | 20 +++++++++ .../include/mcuboot_config/mcuboot_config.h | 5 +-- 5 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 boot/zephyr/external_crypto.conf diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index 5a87f736b..5e79cd1bf 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -34,6 +34,7 @@ #if (defined(MCUBOOT_USE_TINYCRYPT) + \ defined(MCUBOOT_USE_CC310) + \ + defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_PSA_OR_MBED_TLS)) != 1 #error "One crypto backend must be defined: either CC310/TINYCRYPT/MBED_TLS/PSA_CRYPTO" #endif @@ -70,6 +71,11 @@ #include "bootutil/sign_key.h" #include "common.h" +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + #include + #define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (4 * 8) +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus extern "C" { #endif @@ -613,6 +619,43 @@ static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, #endif /* MCUBOOT_USE_MBED_TLS */ +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) +typedef uintptr_t bootutil_ecdsa_p256_context; + +static inline void bootutil_ecdsa_p256_init(bootutil_ecdsa_p256_context *ctx) +{ + (void)ctx; +} + +static inline void bootutil_ecdsa_p256_drop(bootutil_ecdsa_p256_context *ctx) +{ + (void)ctx; +} + +static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, + uint8_t *pk, size_t pk_len, + uint8_t *hash, + uint8_t *sig, size_t sig_len) +{ + (void)ctx; + (void)pk_len; + (void)sig_len; + + /* As described on the compact representation in IETF protocols, + * the first byte of the key defines if the ECC points are + * compressed (0x2 or 0x3) or uncompressed (0x4). + * We only support uncompressed keys. + */ + if (pk[0] != 0x04) + return -1; + + pk++; + + return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, + pk, sig); +} +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus } #endif diff --git a/boot/bootutil/include/bootutil/crypto/sha.h b/boot/bootutil/include/bootutil/crypto/sha.h index 9ce54bee5..28e827fea 100644 --- a/boot/bootutil/include/bootutil/crypto/sha.h +++ b/boot/bootutil/include/bootutil/crypto/sha.h @@ -30,6 +30,7 @@ #if (defined(MCUBOOT_USE_PSA_OR_MBED_TLS) + \ defined(MCUBOOT_USE_TINYCRYPT) + \ + defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_CC310)) != 1 #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO" #endif @@ -206,6 +207,37 @@ static inline int bootutil_sha_finish(bootutil_sha_context *ctx, } #endif /* MCUBOOT_USE_CC310 */ +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + +#include + +typedef bl_sha256_ctx_t bootutil_sha_context; + +static inline void bootutil_sha_init(bootutil_sha_context *ctx) +{ + bl_sha256_init(ctx); +} + +static inline void bootutil_sha_drop(bootutil_sha_context *ctx) +{ + (void)ctx; +} + +static inline int bootutil_sha_update(bootutil_sha_context *ctx, + const void *data, + uint32_t data_len) +{ + return bl_sha256_update(ctx, data, data_len); +} + +static inline int bootutil_sha_finish(bootutil_sha_context *ctx, + uint8_t *output) +{ + bl_sha256_finalize(ctx, output); + return 0; +} +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus } #endif diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 92999a687..d2bdbfb03 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -172,6 +172,8 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) zephyr_library_sources(${NRF_DIR}/cc310_glue.c) zephyr_library_include_directories(${NRF_DIR}) zephyr_link_libraries(nrfxlib_crypto) + elseif(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) + zephyr_include_directories(${BL_CRYPTO_DIR}/../include) endif() # Since here we are not using Zephyr's mbedTLS but rather our own, we need diff --git a/boot/zephyr/external_crypto.conf b/boot/zephyr/external_crypto.conf new file mode 100644 index 000000000..8181ad51c --- /dev/null +++ b/boot/zephyr/external_crypto.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# These configurations should be used when using nrf/samples/bootloader +# as the immutable bootloader (B0), and MCUBoot as the second stage updateable +# bootloader. + +# Set ECDSA as signing mechanism +CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y + +# Use crypto backend from B0 +CONFIG_BOOT_NRF_EXTERNAL_CRYPTO=y +CONFIG_SECURE_BOOT_CRYPTO=y +CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y +CONFIG_SB_CRYPTO_CLIENT_SHA256=y +CONFIG_BL_SHA256_EXT_API_REQUIRED=y +CONFIG_BL_SECP256R1_EXT_API_REQUIRED=y diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 8f5d17bf5..7ef0ae11a 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -40,9 +40,8 @@ #define MCUBOOT_USE_TINYCRYPT #elif defined(CONFIG_BOOT_USE_CC310) #define MCUBOOT_USE_CC310 -#ifdef CONFIG_BOOT_USE_NRF_CC310_BL -#define MCUBOOT_USE_NRF_CC310_BL -#endif +#elif defined(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) +#define MCUBOOT_USE_NRF_EXTERNAL_CRYPTO #endif /* Zephyr, regardless of C library used, provides snprintf */ From a42e9cc5fa46b614e60353d6a255984f72ab4d7e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 21 Apr 2023 15:45:00 +0000 Subject: [PATCH 006/238] [nrf noup] crypto: ecdsa: Add required signature decoding The CC310 and bl_crypto require decoded signature instead of raw ASN.1 Signed-off-by: Dominik Ermel (cherry picked from commit ba5556128b083ddbaee46ec09fb22c6f743c9205) --- boot/bootutil/include/bootutil/crypto/ecdsa.h | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index 5e79cd1bf..eb3e33ee0 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -133,8 +133,6 @@ static int bootutil_import_key(uint8_t **cp, uint8_t *end) } #endif /* (MCUBOOT_USE_TINYCRYPT || MCUBOOT_USE_MBED_TLS || MCUBOOT_USE_CC310) && !MCUBOOT_USE_PSA_CRYPTO */ -#if defined(MCUBOOT_USE_TINYCRYPT) -#ifndef MCUBOOT_ECDSA_NEED_ASN1_SIG /* * cp points to ASN1 string containing an integer. * Verify the tag, and that the length is 32 bytes. Helper function. @@ -184,8 +182,8 @@ static int bootutil_decode_sig(uint8_t signature[NUM_ECC_BYTES * 2], uint8_t *cp } return 0; } -#endif /* not MCUBOOT_ECDSA_NEED_ASN1_SIG */ +#if defined(MCUBOOT_USE_TINYCRYPT) typedef uintptr_t bootutil_ecdsa_context; static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) { @@ -254,8 +252,12 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, { (void)ctx; (void)pk_len; - (void)sig_len; (void)hash_len; + uint8_t dsig[2 * NUM_ECC_BYTES]; + + if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { + return -1; + } /* Only support uncompressed keys. */ if (pk[0] != 0x04) { @@ -263,7 +265,7 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, } pk++; - return cc310_ecdsa_verify_secp256r1(hash, pk, sig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); + return cc310_ecdsa_verify_secp256r1(hash, pk, dsig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); } static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, @@ -639,7 +641,11 @@ static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, { (void)ctx; (void)pk_len; - (void)sig_len; + uint8_t dsig[2 * NUM_ECC_BYTES]; + + if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { + return -1; + } /* As described on the compact representation in IETF protocols, * the first byte of the key defines if the ECC points are @@ -652,7 +658,7 @@ static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, pk++; return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, - pk, sig); + pk, dsig); } #endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ From 895c76beb540d91cd9ddb53198bbfde0089c36d4 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Tue, 10 Oct 2023 14:05:04 +0200 Subject: [PATCH 007/238] [nrf noup] crypto: ecdsa: Fix shared crypto MCUBoot EXT_ABI After the upmerge using external crypto from NSIB in MCUBoot resulted in build failures. This commit fixes the build failures but also fixes a change in the API call which resulted in `-102` error when calling the verify function. Ref. NCSDK-23994 Signed-off-by: Sigvart Hovland Signed-off-by: Dominik Ermel (cherry picked from commit a0c21e290d2618942ea8b340e976a54464d300a9) --- boot/bootutil/include/bootutil/crypto/ecdsa.h | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index eb3e33ee0..450450dc3 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -73,7 +73,7 @@ #if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) #include - #define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (4 * 8) + #define NUM_ECC_BYTES (256 / 8) #endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ #ifdef __cplusplus @@ -81,7 +81,8 @@ extern "C" { #endif #if (defined(MCUBOOT_USE_TINYCRYPT) || defined(MCUBOOT_USE_MBED_TLS) || \ - defined(MCUBOOT_USE_CC310)) && !defined(MCUBOOT_USE_PSA_CRYPTO) + defined(MCUBOOT_USE_CC310) || defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO)) \ + && !defined(MCUBOOT_USE_PSA_CRYPTO) /* * Declaring these like this adds NULL termination. */ @@ -622,43 +623,45 @@ static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, #endif /* MCUBOOT_USE_MBED_TLS */ #if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) -typedef uintptr_t bootutil_ecdsa_p256_context; - -static inline void bootutil_ecdsa_p256_init(bootutil_ecdsa_p256_context *ctx) +typedef uintptr_t bootutil_ecdsa_context; +static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) { (void)ctx; } -static inline void bootutil_ecdsa_p256_drop(bootutil_ecdsa_p256_context *ctx) +static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx) { (void)ctx; } -static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, - uint8_t *pk, size_t pk_len, - uint8_t *hash, - uint8_t *sig, size_t sig_len) +static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, + uint8_t *pk, size_t pk_len, + uint8_t *hash, size_t hash_len, + uint8_t *sig, size_t sig_len) { (void)ctx; (void)pk_len; + (void)hash_len; uint8_t dsig[2 * NUM_ECC_BYTES]; if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { return -1; } - /* As described on the compact representation in IETF protocols, - * the first byte of the key defines if the ECC points are - * compressed (0x2 or 0x3) or uncompressed (0x4). - * We only support uncompressed keys. - */ - if (pk[0] != 0x04) - return -1; + /* Only support uncompressed keys. */ + if (pk[0] != 0x04) { + return -1; + } + pk++; - pk++; + return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, pk, dsig); +} - return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, - pk, dsig); +static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, + uint8_t **cp,uint8_t *end) +{ + (void)ctx; + return bootutil_import_key(cp, end); } #endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ From ff5338297c4be31e757f99d8cf5730b05a5cbed6 Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Mon, 8 Nov 2021 22:58:59 +0100 Subject: [PATCH 008/238] [nrf noup] zephyr: Set at least provide EXT_API -This sets the provide EXT_API to be at least optional when the external_crypto is being used. Ref: NCSDK-12021 Signed-off-by: Georgios Vasilakis Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit fcd7281e6ffd386d5f28b1af62ece96b9945b2ab) --- boot/zephyr/external_crypto.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/external_crypto.conf b/boot/zephyr/external_crypto.conf index 8181ad51c..c362f000a 100644 --- a/boot/zephyr/external_crypto.conf +++ b/boot/zephyr/external_crypto.conf @@ -18,3 +18,4 @@ CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y CONFIG_SB_CRYPTO_CLIENT_SHA256=y CONFIG_BL_SHA256_EXT_API_REQUIRED=y CONFIG_BL_SECP256R1_EXT_API_REQUIRED=y +CONFIG_EXT_API_PROVIDE_EXT_API_ATLEAST_OPTIONAL=y From cffdc5207003743f1951e2d4a84cc9e9dcc35eee Mon Sep 17 00:00:00 2001 From: Damian Krolik Date: Mon, 21 Mar 2022 13:44:27 +0100 Subject: [PATCH 009/238] [nrf noup] zephyr: Restore default RTC user channel count The default value of CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT for nRF52 SOCs has been changed from 0 to 3, but it makes MCUBoot get stuck on erasing flash pages when swapping two images. Restore the previous value until the RTC issue is resolved (see NCSDK-14427) Signed-off-by: Damian Krolik Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit a01d30a9906ee0b874f48c8f12f05185cc4e4a8e) --- boot/zephyr/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 851c133ec..58cb2ae35 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -35,3 +35,4 @@ CONFIG_MCUBOOT_LOG_LEVEL_INF=y CONFIG_CBPRINTF_NANO=y ### Use the minimal C library to reduce flash usage CONFIG_MINIMAL_LIBC=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 From 916a9dcb137df96c435cc1b63b20ba265957ae51 Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Fri, 8 Dec 2023 13:18:12 +0100 Subject: [PATCH 010/238] [nrf noup] boards: thingy91x: add board config This patch adds board configuration for the Thingy:91 X. Signed-off-by: Maximilian Deubel (cherry picked from commit 3c2f2ff12bc20625cd65730b6036d061de4da5f7) --- .../boards/thingy91x_nrf5340_cpuapp.conf | 54 +++++++++++++++++++ boot/zephyr/boards/thingy91x_nrf9151.conf | 8 +++ 2 files changed, 62 insertions(+) create mode 100644 boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf create mode 100644 boot/zephyr/boards/thingy91x_nrf9151.conf diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf new file mode 100644 index 000000000..72dfa7fca --- /dev/null +++ b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf @@ -0,0 +1,54 @@ +# MCUBoot settings +CONFIG_BOOT_MAX_IMG_SECTORS=110 + +# MCUboot serial recovery +CONFIG_MCUBOOT_SERIAL=y + +# Disable Zephyr console +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n + +# Serial +CONFIG_SERIAL=y +CONFIG_UART_NRFX=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_LINE_CTRL=y + +# MCUboot serial recovery +CONFIG_GPIO=y +CONFIG_MCUBOOT_SERIAL=y +CONFIG_BOOT_SERIAL_CDC_ACM=y + +# Required by USB +CONFIG_MULTITHREADING=y + +# USB +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_PRODUCT="MCUBOOT" +CONFIG_USB_CDC_ACM=y +CONFIG_USB_COMPOSITE_DEVICE=y +CONFIG_USB_MASS_STORAGE=n +CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" +CONFIG_USB_DEVICE_VID=0x1915 +CONFIG_USB_DEVICE_PID=0x520F + +CONFIG_BOOT_SERIAL_BOOT_MODE=y + +CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x13E00 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 +CONFIG_BOOT_UPGRADE_ONLY=y +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y + +CONFIG_NRF53_RECOVERY_NETWORK_CORE=y diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf new file mode 100644 index 000000000..33cd3301c --- /dev/null +++ b/boot/zephyr/boards/thingy91x_nrf9151.conf @@ -0,0 +1,8 @@ +# MCUBoot settings +CONFIG_BOOT_MAX_IMG_SECTORS=512 + +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_SPI_NOR_SFDP_DEVICETREE=y +CONFIG_MULTITHREADING=y From 9555ca78469efc3ddc7cd2712edcae6de1befdb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Wed, 12 Dec 2018 08:59:47 +0100 Subject: [PATCH 011/238] [nrf noup] treewide: add NCS partition manager support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partition Manager is an nRF Connect SDK component which uses yaml files to resolve flash partition placement with a holistic view of the device. This component's MCUboot portions began life as upstream mcuboot PR#430. This added support for being built as a sub image from the downstream Nordic patch set for a zephyr multi image build system (mcuboot 430 was combined with effor submitted to upstream zephyr as PR#13672, which was ultimately reworked after being rejected for mainline at the ELCE 2019 conference in Lyon). It has since evolved over time. This is the version that will go into NCS v1.3. It features: - page size aligned partitions for all partitions used by mcuboot. - image swaps without scratch partitions Add support for configurations where there exists two primary slots but only one secondary slot, which is shared. These two primary slots are the regular application and B1. B1 can be either S0 or S1 depending on the state of the device. Decide where an upgrade should be stored by looking at the vector table. Provide update candidates for both s0 and s1. These candidates must be signed with mcuboot after being signed by b0. Additional notes: - we make update.hex without trailer data This is needed for serial recovery to work using hex files. Prior to this the update.hex got TLV data at the end of the partition, which caused many blank pages to be included, which made it hard to use in a serial recovery scheme. Instead, make update.hex without TLV data at the end, and provide a new file test_update.hex which contains the TLV data, and can be directly flashed to test the upgrade procedure. - we use a function for signing the application as future-proofing for when other components must be signed as well - this includes an update to single image applications that enables support for partition manager; when single image DFU is used, a scratch partition is not needed. - In NCS, image 1 primary slot is the upgrade bank for mcuboot (IE S0 or S1 depending on the active slot). It is not required that this slot contains any valid data. - The nRF boards all have a single flash page size, and partition manager deals with the size of the update partitions and so on, so we must skip a boot_slots_compatible() check to avoid getting an error. - There is no need to verify the target when using partition manager. - We lock mcuboot using fprotect before jumping, to enable the secure boot property of the system. - Call fw_info_ext_api_provide() before booting if EXT_API_PROVIDE EXT_API is enabled. This is relevant only when the immutable bootloader has booted mcuboot. Signed-off-by: Håkon Øye Amundsen Signed-off-by: Øyvind Rønningstad Signed-off-by: Sebastian Bøe Signed-off-by: Sigvart Hovland Signed-off-by: Martí Bolívar Signed-off-by: Torsten Rasmussen Signed-off-by: Andrzej Głąbek Signed-off-by: Robert Lubos Signed-off-by: Andrzej Puzdrowski Signed-off-by: Emil Obalski Signed-off-by: Pawel Dunaj Signed-off-by: Ioannis Glaropoulos Signed-off-by: Johann Fischer Signed-off-by: Vidar Berg Signed-off-by: Draus, Sebastian Signed-off-by: Trond Einar Snekvik Signed-off-by: Jamie McCrae Signed-off-by: Joakim Andersson Signed-off-by: Georgios Vasilakis Signed-off-by: Dominik Ermel (cherry picked from commit 518617a4921c66e637073753370974743127412c) --- boot/bootutil/src/loader.c | 95 ++++++++++++++++++++++--- boot/bootutil/src/swap_move.c | 13 ++++ boot/bootutil/src/swap_scratch.c | 13 ++++ boot/zephyr/CMakeLists.txt | 7 ++ boot/zephyr/Kconfig | 2 + boot/zephyr/include/sysflash/sysflash.h | 48 +++++++++++++ boot/zephyr/include/target.h | 4 ++ boot/zephyr/main.c | 45 ++++++++++++ boot/zephyr/pm.yml | 74 +++++++++++++++++++ boot/zephyr/prj.conf | 1 + ext/nrf/cc310_glue.h | 2 +- zephyr/module.yml | 3 +- 12 files changed, 296 insertions(+), 11 deletions(-) create mode 100644 boot/zephyr/pm.yml diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index bd3a7f09c..e9f98f547 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -111,6 +111,15 @@ boot_read_image_headers(struct boot_loader_state *state, bool require_all, * * Failure to read any headers is a fatal error. */ +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. The primary slot of the second image + * (image 1) will not contain a valid image header until an upgrade + * of mcuboot has happened (filling S1 with the new version). + */ + if (BOOT_CURR_IMG(state) == 1 && i == 0) { + continue; + } +#endif /* PM_S1_ADDRESS */ if (i > 0 && !require_all) { return 0; } else { @@ -1056,7 +1065,24 @@ boot_validate_slot(struct boot_loader_state *state, int slot, goto out; } - if (reset_value < pri_fa->fa_off || reset_value> (pri_fa->fa_off + pri_fa->fa_size)) { + uint32_t min_addr, max_addr; + +#ifdef PM_CPUNET_APP_ADDRESS + /* The primary slot for the network core is emulated in RAM. + * Its flash_area hasn't got relevant boundaries. + * Therfore need to override its boundaries for the check. + */ + if (BOOT_CURR_IMG(state) == 1) { + min_addr = PM_CPUNET_APP_ADDRESS; + max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; + } else +#endif + { + min_addr = pri_fa->fa_off; + max_addr = pri_fa->fa_off + pri_fa->fa_size; + } + + if (reset_value < min_addr || reset_value> (max_addr)) { BOOT_LOG_ERR("Reset address of image in secondary slot is not in the primary slot"); BOOT_LOG_ERR("Erasing image from secondary slot"); @@ -1139,6 +1165,42 @@ boot_validated_swap_type(struct boot_loader_state *state, { int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other + * B1 slot S0 or S1) share the same secondary slot, we need to check + * whether the update candidate in the secondary slot is intended for + * image 0 or image 1 primary by looking at the address of the reset + * vector. Note that there are good reasons for not using img_num from + * the swap info. + */ + const struct flash_area *secondary_fa = + BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); + struct image_header *hdr = + (struct image_header *)secondary_fa->fa_off; + + if (hdr->ih_magic == IMAGE_MAGIC) { + const struct flash_area *primary_fa; + uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + uint32_t *vtable = (uint32_t *)(vtable_addr); + uint32_t reset_addr = vtable[1]; + int rc = flash_area_open( + flash_area_id_from_multi_image_slot( + BOOT_CURR_IMG(state), + BOOT_PRIMARY_SLOT), + &primary_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + /* Get start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off || + reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for this image + */ + return BOOT_SWAP_TYPE_NONE; + } + } +#endif swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -2301,15 +2363,25 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } #ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT - FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL); - /* Check for all possible values is redundant in normal operation it - * is meant to prevent FI attack. +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. Image 1 primary is the currently + * executing MCUBoot image, and is therefore already validated by NSIB and + * does not need to also be validated by MCUBoot. */ - if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS) || - FIH_EQ(fih_rc, FIH_FAILURE) || - FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) { - FIH_SET(fih_rc, FIH_FAILURE); - goto out; + bool image_validated_by_nsib = BOOT_CURR_IMG(state) == 1; + if (!image_validated_by_nsib) +#endif + { + FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL); + /* Check for all possible values is redundant in normal operation it + * is meant to prevent FI attack. + */ + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS) || + FIH_EQ(fih_rc, FIH_FAILURE) || + FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } } #else /* Even if we're not re-validating the primary slot, we could be booting @@ -2326,11 +2398,16 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } #endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */ +#ifdef PM_S1_ADDRESS + if (!image_validated_by_nsib) +#endif + { rc = boot_update_hw_rollback_protection(state); if (rc != 0) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } + } rc = boot_add_shared_data(state, BOOT_PRIMARY_SLOT); if (rc != 0) { diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 111e82f05..5e6723bb6 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -259,6 +259,18 @@ static int app_max_sectors(struct boot_loader_state *state) int boot_slots_compatible(struct boot_loader_state *state) { +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. In this case, image 1 primary points to the other + * B1 slot (ie S0 or S1), and image 0 primary points to the app. + * With this configuration, image 0 and image 1 share the secondary slot. + * Hence, the primary slot of image 1 will be *smaller* than image 1's + * secondary slot. This is not allowed in upstream mcuboot, so we need + * this patch to allow it. Also, all of these checks are redundant when + * partition manager is in use, and since we have the same sector size + * in all of our flash. + */ + return 1; +#else size_t num_sectors_pri; size_t num_sectors_sec; size_t sector_sz_pri = 0; @@ -306,6 +318,7 @@ boot_slots_compatible(struct boot_loader_state *state) } return 1; +#endif /* PM_S1_ADDRESS */ } #define BOOT_LOG_SWAP_STATE(area, state) \ diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index 66cbdce5f..a32eb8d87 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -170,6 +170,18 @@ boot_status_internal_off(const struct boot_status *bs, int elem_sz) int boot_slots_compatible(struct boot_loader_state *state) { +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. In this case, image 1 primary points to the other + * B1 slot (ie S0 or S1), and image 0 primary points to the app. + * With this configuration, image 0 and image 1 share the secondary slot. + * Hence, the primary slot of image 1 will be *smaller* than image 1's + * secondary slot. This is not allowed in upstream mcuboot, so we need + * this patch to allow it. Also, all of these checks are redundant when + * partition manager is in use, and since we have the same sector size + * in all of our flash. + */ + return 1; +#else size_t num_sectors_primary; size_t num_sectors_secondary; size_t sz0, sz1; @@ -255,6 +267,7 @@ boot_slots_compatible(struct boot_loader_state *state) } return 1; +#endif /* PM_S1_ADDRESS */ } #define BOOT_LOG_SWAP_STATE(area, state) \ diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index d2bdbfb03..f5fb109e8 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -297,6 +297,13 @@ if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "") endif() message("MCUBoot bootloader key file: ${KEY_FILE}") + set_property( + GLOBAL + PROPERTY + KEY_FILE + ${KEY_FILE} + ) + set(GENERATED_PUBKEY ${ZEPHYR_BINARY_DIR}/autogen-pubkey.c) add_custom_command( OUTPUT ${GENERATED_PUBKEY} diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index effedfb4f..4b134b28f 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -9,6 +9,8 @@ mainmenu "MCUboot configuration" comment "MCUboot-specific configuration options" +source "$(ZEPHYR_NRF_MODULE_DIR)/modules/mcuboot/boot/zephyr/Kconfig" + # Hidden option to mark a project as MCUboot config MCUBOOT default y diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 1952950b9..4eaf0309e 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -7,6 +7,52 @@ #ifndef __SYSFLASH_H__ #define __SYSFLASH_H__ +#if USE_PARTITION_MANAGER +#include +#include + +#ifndef CONFIG_SINGLE_APPLICATION_SLOT + +#if (MCUBOOT_IMAGE_NUMBER == 1) + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID + +#elif (MCUBOOT_IMAGE_NUMBER == 2) + +extern uint32_t _image_1_primary_slot_id[]; + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + (uint32_t)_image_1_primary_slot_id : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + 255 ) +#endif +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID + +#else /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID +/* NOTE: Scratch parition is not used by single image DFU but some of + * functions in common files reference it, so the definitions has been + * provided to allow compilation of common units. + */ +#define FLASH_AREA_IMAGE_SCRATCH 0 + +#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#else + +#include #include #include #include @@ -65,4 +111,6 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ +#endif /* USE_PARTITION_MANAGER */ + #endif /* __SYSFLASH_H__ */ diff --git a/boot/zephyr/include/target.h b/boot/zephyr/include/target.h index 9bbfd4b19..40287d515 100644 --- a/boot/zephyr/include/target.h +++ b/boot/zephyr/include/target.h @@ -8,6 +8,8 @@ #ifndef H_TARGETS_TARGET_ #define H_TARGETS_TARGET_ +#ifndef USE_PARTITION_MANAGER + #if defined(MCUBOOT_TARGET_CONFIG) /* * Target-specific definitions are permitted in legacy cases that @@ -45,4 +47,6 @@ #error "Target support is incomplete; cannot build mcuboot." #endif +#endif /* ifndef USE_PARTITION_MANAGER */ + #endif /* H_TARGETS_TARGET_ */ diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 95da276bd..df4c33937 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -69,6 +69,10 @@ #endif /* CONFIG_SOC_FAMILY_ESPRESSIF_ESP32 */ +#ifdef CONFIG_FW_INFO +#include +#endif + #ifdef CONFIG_MCUBOOT_SERIAL #include "boot_serial/boot_serial.h" #include "serial_adapter/serial_adapter.h" @@ -129,6 +133,11 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); * !defined(ZEPHYR_LOG_MODE_MINIMAL) */ +#if USE_PARTITION_MANAGER && CONFIG_FPROTECT +#include +#include +#endif + BOOT_LOG_MODULE_REGISTER(mcuboot); void os_heap_init(void); @@ -187,6 +196,19 @@ static void do_boot(struct boot_rsp *rsp) /* Disable the USB to prevent it from firing interrupts */ usb_disable(); #endif + +#if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) + bool provided = fw_info_ext_api_provide(fw_info_find((uint32_t)vt), true); + +#ifdef PM_S0_ADDRESS + /* Only fail if the immutable bootloader is present. */ + if (!provided) { + BOOT_LOG_ERR("Failed to provide EXT_APIs\n"); + return; + } +#endif +#endif + #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ @@ -545,7 +567,30 @@ int main(void) mcuboot_status_change(MCUBOOT_STATUS_BOOTABLE_IMAGE_FOUND); +#if USE_PARTITION_MANAGER && CONFIG_FPROTECT + +#ifdef PM_S1_ADDRESS +/* MCUBoot is stored in either S0 or S1, protect both */ +#define PROTECT_SIZE (PM_MCUBOOT_PRIMARY_ADDRESS - PM_S0_ADDRESS) +#define PROTECT_ADDR PM_S0_ADDRESS +#else +/* There is only one instance of MCUBoot */ +#define PROTECT_SIZE (PM_MCUBOOT_PRIMARY_ADDRESS - PM_MCUBOOT_ADDRESS) +#define PROTECT_ADDR PM_MCUBOOT_ADDRESS +#endif + + rc = fprotect_area(PROTECT_ADDR, PROTECT_SIZE); + + if (rc != 0) { + BOOT_LOG_ERR("Protect mcuboot flash failed, cancel startup."); + while (1) + ; + } + +#endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ + ZEPHYR_BOOT_LOG_STOP(); + do_boot(&rsp); mcuboot_status_change(MCUBOOT_STATUS_BOOT_FAILED); diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml new file mode 100644 index 000000000..0c3a59154 --- /dev/null +++ b/boot/zephyr/pm.yml @@ -0,0 +1,74 @@ +#include + +mcuboot: + size: CONFIG_PM_PARTITION_SIZE_MCUBOOT + placement: + before: [mcuboot_primary] + +mcuboot_primary_app: + # All images to be placed in MCUboot's slot 0 should be placed in this + # partition + span: [app] + +mcuboot_primary: + span: [mcuboot_pad, mcuboot_primary_app] + +# Partition for secondary slot is not created if building in single application +# slot configuration. +#if !defined(CONFIG_SINGLE_APPLICATION_SLOT) && !defined(CONFIG_BOOT_DIRECT_XIP) +mcuboot_secondary: + share_size: [mcuboot_primary] +#if defined(CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY) + region: external_flash + placement: + align: {start: 4} +#else + placement: + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} + align_next: CONFIG_FPROTECT_BLOCK_SIZE # Ensure that the next partition does not interfere with this image + after: mcuboot_primary +#endif /* CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY */ + +#endif /* !defined(CONFIG_SINGLE_APPLICATION_SLOT) && !defined(CONFIG_BOOT_DIRECT_XIP) */ + +#if CONFIG_BOOT_DIRECT_XIP + +# Direct XIP is enabled, reserve area for metadata (padding) and name the +# partition so that its clear that it is not the secondary slot, but the direct +# XIP alternative. + +mcuboot_secondary_pad: + share_size: mcuboot_pad + placement: + after: mcuboot_primary + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} + +mcuboot_secondary_app: + share_size: mcuboot_primary_app + placement: + after: mcuboot_secondary_pad + +mcuboot_secondary: + span: [mcuboot_secondary_pad, mcuboot_secondary_app] + +#endif /* CONFIG_BOOT_DIRECT_XIP */ + +#if CONFIG_BOOT_SWAP_USING_SCRATCH +mcuboot_scratch: + size: CONFIG_PM_PARTITION_SIZE_MCUBOOT_SCRATCH + placement: + after: app + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} +#endif /* CONFIG_BOOT_SWAP_USING_SCRATCH */ + +# Padding placed before image to boot. This reserves space for the MCUboot image header +# and it ensures that the boot image gets linked with the correct address offset in flash. +mcuboot_pad: + # MCUboot pad must be placed before the primary application partition. + # The primary application partition includes the secure firmware if present. + size: CONFIG_PM_PARTITION_SIZE_MCUBOOT_PAD + placement: + before: [mcuboot_primary_app] +#ifdef CONFIG_FPROTECT + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} +#endif diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 58cb2ae35..23b5f3b93 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -19,6 +19,7 @@ CONFIG_BOOT_BOOTSTRAP=n # CONFIG_TINYCRYPT_SHA256 is not set CONFIG_FLASH=y +CONFIG_FPROTECT=y ### Various Zephyr boards enable features that we don't want. # CONFIG_BT is not set diff --git a/ext/nrf/cc310_glue.h b/ext/nrf/cc310_glue.h index ed3ed5c00..22eb94911 100644 --- a/ext/nrf/cc310_glue.h +++ b/ext/nrf/cc310_glue.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include /* diff --git a/zephyr/module.yml b/zephyr/module.yml index 014a21956..9360dbf70 100644 --- a/zephyr/module.yml +++ b/zephyr/module.yml @@ -1,5 +1,6 @@ samples: - boot/zephyr build: - cmake: ./boot/bootutil/zephyr + cmake-ext: True + kconfig-ext: True sysbuild-cmake: boot/zephyr/sysbuild From cab8ef90e391f3b230ccc3657c7cac2bf9d52413 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Thu, 27 Aug 2020 14:29:31 +0200 Subject: [PATCH 012/238] [nrf noup] boot: nrf53-specific customizations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add network core bootloader implementation Enables network core updates of nrf53 using MCUBoot by identifying images through their start addresses. Also implements the control and transfer using the PCD module. - Add support for multi image DFU using partition manager. - Add check for netcore addr if NSIB is enabled so netcore updates works - boot: zephyr: move thingy53_nrf5340_cpuapp.conf downstream Moved the board configuration for Thingy:53 Application Core to the nRF Connect SDK MCUboot downstream repository. The configuration file contains references to the Kconfig modules that are only available in the nRF Connect SDK. The current configuration is set up to work in the nRF Connect SDK environment and cannot be used upstream. - pm: enable ram flash partition using common flag This patch makes mcuboot_primary_1 ram-flash partition selectable using CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH property. This is needed since CONFIG_NRF53_MULTI_IMAGE_UPDATE become not only configuration which requires that partition. - MCUBoot configures USB CDC by its own. There is no need for BOARD_SERIAL_BACKEND_CDC_ACM option to configure anything which is later overwritten anyway. Jira: NCSDK-18596 Signed-off-by: Andrzej Puzdrowski Signed-off-by: Emil Obalski Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Jamie McCrae Signed-off-by: Johann Fischer Signed-off-by: Kamil Piszczek Signed-off-by: Ole Sæther Signed-off-by: Sigvart Hovland Signed-off-by: Simon Iversen Signed-off-by: Torsten Rasmussen Signed-off-by: Trond Einar Snekvik Signed-off-by: Mateusz Kapala Signed-off-by: Dominik Ermel (cherry picked from commit 42e43d04e0b2327ac0722b070a3b2fa11f17fa34) --- boot/bootutil/src/loader.c | 96 ++++++++++++++----- .../boards/thingy53_nrf5340_cpuapp.conf | 73 ++++++++++++++ boot/zephyr/include/sysflash/sysflash.h | 23 +++++ boot/zephyr/main.c | 7 ++ boot/zephyr/pm.yml | 13 +++ 5 files changed, 186 insertions(+), 26 deletions(-) create mode 100644 boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index e9f98f547..568c28e45 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,6 +49,10 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) +#include +#endif + #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" #endif @@ -1165,7 +1169,15 @@ boot_validated_swap_type(struct boot_loader_state *state, { int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); -#ifdef PM_S1_ADDRESS + bool upgrade_valid = false; + +#if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) + const struct flash_area *secondary_fa = + BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); + struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; + uint32_t vtable_addr = 0; + uint32_t *vtable = 0; + uint32_t reset_addr = 0; /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other * B1 slot S0 or S1) share the same secondary slot, we need to check * whether the update candidate in the secondary slot is intended for @@ -1173,34 +1185,36 @@ boot_validated_swap_type(struct boot_loader_state *state, * vector. Note that there are good reasons for not using img_num from * the swap info. */ - const struct flash_area *secondary_fa = - BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = - (struct image_header *)secondary_fa->fa_off; if (hdr->ih_magic == IMAGE_MAGIC) { - const struct flash_area *primary_fa; - uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - uint32_t *vtable = (uint32_t *)(vtable_addr); - uint32_t reset_addr = vtable[1]; - int rc = flash_area_open( - flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), - BOOT_PRIMARY_SLOT), - &primary_fa); - - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } - /* Get start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off || - reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for this image - */ - return BOOT_SWAP_TYPE_NONE; - } - } + vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + vtable = (uint32_t *)(vtable_addr); + reset_addr = vtable[1]; +#ifdef PM_S1_ADDRESS +#ifdef PM_CPUNET_B0N_ADDRESS + if(reset_addr < PM_CPUNET_B0N_ADDRESS) #endif + { + const struct flash_area *primary_fa; + int rc = flash_area_open(flash_area_id_from_multi_image_slot( + BOOT_CURR_IMG(state), + BOOT_PRIMARY_SLOT), + &primary_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + /* Get start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off || + reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for this image + */ + return BOOT_SWAP_TYPE_NONE; + } + } +#endif /* PM_S1_ADDRESS */ + } +#endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -1214,7 +1228,37 @@ boot_validated_swap_type(struct boot_loader_state *state, } else { swap_type = BOOT_SWAP_TYPE_FAIL; } + } else { + upgrade_valid = true; + } + +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) + /* If the update is valid, and it targets the network core: perform the + * update and indicate to the caller of this function that no update is + * available + */ + if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { + uint32_t fw_size = hdr->ih_img_size; + + BOOT_LOG_INF("Starting network core update"); + int rc = pcd_network_core_update(vtable, fw_size); + + if (rc != 0) { + swap_type = BOOT_SWAP_TYPE_FAIL; + } else { + BOOT_LOG_INF("Done updating network core"); +#if defined(MCUBOOT_SWAP_USING_SCRATCH) || defined(MCUBOOT_SWAP_USING_MOVE) + /* swap_erase_trailer_sectors is undefined if upgrade only + * method is used. There is no need to erase sectors, because + * the image cannot be reverted. + */ + rc = swap_erase_trailer_sectors(state, + secondary_fa); +#endif + swap_type = BOOT_SWAP_TYPE_NONE; + } } +#endif /* CONFIG_SOC_NRF5340_CPUAPP */ } return swap_type; diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf new file mode 100644 index 000000000..7d3bc0bec --- /dev/null +++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf @@ -0,0 +1,73 @@ +CONFIG_SIZE_OPTIMIZATIONS=y + +CONFIG_SYSTEM_CLOCK_NO_WAIT=y +CONFIG_PM=n + +CONFIG_MAIN_STACK_SIZE=10240 +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +CONFIG_BOOT_MAX_IMG_SECTORS=2048 +CONFIG_BOOT_SIGNATURE_TYPE_RSA=y + +# Flash +CONFIG_FLASH=y +CONFIG_BOOT_ERASE_PROGRESSIVELY=y +CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y +CONFIG_FPROTECT=y + +# Serial +CONFIG_SERIAL=y +CONFIG_UART_LINE_CTRL=y + +# MCUBoot serial +CONFIG_GPIO=y +CONFIG_MCUBOOT_SERIAL=y +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +CONFIG_BOOT_SERIAL_CDC_ACM=y + +# Required by QSPI +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# Required by USB and QSPI +CONFIG_MULTITHREADING=y + +# USB +CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n +CONFIG_USB_DEVICE_REMOTE_WAKEUP=n +CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor ASA" +CONFIG_USB_DEVICE_PRODUCT="Bootloader Thingy:53" +CONFIG_USB_DEVICE_VID=0x1915 +CONFIG_USB_DEVICE_PID=0x5300 +CONFIG_USB_CDC_ACM=y + +# Decrease memory footprint +CONFIG_CBPRINTF_NANO=y +CONFIG_TIMESLICING=n +CONFIG_BOOT_BANNER=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_LOG=n +CONFIG_ERRNO=n +CONFIG_PRINTK=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_SPI=n +CONFIG_I2C=n +CONFIG_UART_NRFX=n + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 +CONFIG_BOOT_UPGRADE_ONLY=y +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +# Enable custom command to erase settings partition. +CONFIG_ENABLE_MGMT_PERUSER=y +CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 4eaf0309e..b98e48bce 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -20,6 +20,11 @@ #elif (MCUBOOT_IMAGE_NUMBER == 2) +/* If B0 is present then two bootloaders are present, and we must use + * a single secondary slot for both primary slots. + */ +#ifdef PM_B0_ADDRESS + extern uint32_t _image_1_primary_slot_id[]; #define FLASH_AREA_IMAGE_PRIMARY(x) \ @@ -35,6 +40,24 @@ extern uint32_t _image_1_primary_slot_id[]; (x == 1) ? \ PM_MCUBOOT_SECONDARY_ID: \ 255 ) +#else + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) + +#endif /* PM_B0_ADDRESS */ + #endif #define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index df4c33937..fe37ff01d 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -91,6 +91,10 @@ const struct boot_uart_funcs boot_funcs = { #include #endif +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) +#include +#endif + /* CONFIG_LOG_MINIMAL is the legacy Kconfig property, * replaced by CONFIG_LOG_MODE_MINIMAL. */ @@ -587,6 +591,9 @@ int main(void) ; } +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) && defined(CONFIG_PCD_APP) + pcd_lock_ram(); +#endif #endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ ZEPHYR_BOOT_LOG_STOP(); diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml index 0c3a59154..125b8813c 100644 --- a/boot/zephyr/pm.yml +++ b/boot/zephyr/pm.yml @@ -72,3 +72,16 @@ mcuboot_pad: #ifdef CONFIG_FPROTECT align: {start: CONFIG_FPROTECT_BLOCK_SIZE} #endif + +#if (CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH) +mcuboot_primary_1: + region: ram_flash + size: CONFIG_NRF53_RAM_FLASH_SIZE +#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ + +#if (CONFIG_NRF53_MULTI_IMAGE_UPDATE) +mcuboot_secondary_1: + region: external_flash + size: CONFIG_NRF53_RAM_FLASH_SIZE + +#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ From c033da00051c89b9534bbf764867f9479b0cf352 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 27 Feb 2020 12:48:56 +0100 Subject: [PATCH 013/238] [nrf noup] zephyr: clean peripherals state before boot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do some cleanup of nRF peripherals. This is necessary since Zephyr doesn't have any driver deinitialization functionality, and we'd like to leave peripherals in a more predictable state before booting the Zephyr image. This should be re-worked when the zephyr driver model allows us to deinitialize devices cleanly before jumping to the chain-loaded image. Signed-off-by: Andrzej Puzdrowski Signed-off-by: Robert Lubos Signed-off-by: Torsten Rasmussen Signed-off-by: Øyvind Rønningstad Signed-off-by: Martí Bolívar Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Johann Fischer Signed-off-by: Trond Einar Snekvik Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 3b2a5baea3a31a399508f338ccf2e0696939451a) --- boot/zephyr/CMakeLists.txt | 6 +++ boot/zephyr/include/nrf_cleanup.h | 19 +++++++ boot/zephyr/main.c | 8 ++- boot/zephyr/nrf_cleanup.c | 83 +++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 boot/zephyr/include/nrf_cleanup.h create mode 100644 boot/zephyr/nrf_cleanup.c diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index f5fb109e8..4716f8932 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -529,3 +529,9 @@ if(SYSBUILD) set(mcuboot_image_footer_size ${required_size} CACHE INTERNAL "Estimated MCUboot image trailer size" FORCE) set(mcuboot_image_upgrade_footer_size ${required_upgrade_size} CACHE INTERNAL "Estimated MCUboot update image trailer size" FORCE) endif() + +if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL) +zephyr_library_sources( + ${BOOT_DIR}/zephyr/nrf_cleanup.c +) +endif() diff --git a/boot/zephyr/include/nrf_cleanup.h b/boot/zephyr/include/nrf_cleanup.h new file mode 100644 index 000000000..6b04cedfe --- /dev/null +++ b/boot/zephyr/include/nrf_cleanup.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef H_NRF_CLEANUP_ +#define H_NRF_CLEANUP_ + +/** + * Perform cleanup on some peripheral resources used by MCUBoot prior chainload + * the application. + * + * This function disables all RTC instances and UARTE instances. + * It Disables their interrupts signals as well. + */ +void nrf_cleanup_peripheral(void); + +#endif diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index fe37ff01d..cd4e6cb46 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -142,6 +142,10 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); #include #endif +#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL +#include +#endif + BOOT_LOG_MODULE_REGISTER(mcuboot); void os_heap_init(void); @@ -212,7 +216,9 @@ static void do_boot(struct boot_rsp *rsp) } #endif #endif - +#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL + nrf_cleanup_peripheral(); +#endif #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c new file mode 100644 index 000000000..5bab26b24 --- /dev/null +++ b/boot/zephyr/nrf_cleanup.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#if defined(NRF_UARTE0) || defined(NRF_UARTE1) + #include +#endif +#if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) + #include +#endif +#if defined(NRF_PPI) + #include +#endif +#if defined(NRF_DPPIC) + #include +#endif + +#include + +#define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) +#define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ + NRF_UARTE_SUBSCRIBE_CONF_OFFS) + +#define NRF_UARTE_PUBLISH_CONF_OFFS offsetof(NRF_UARTE_Type, PUBLISH_CTS) +#define NRF_UARTE_PUBLISH_CONF_SIZE (offsetof(NRF_UARTE_Type, SHORTS) -\ + NRF_UARTE_PUBLISH_CONF_OFFS) + +#if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) +static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) +{ + nrf_rtc_task_trigger(rtc_reg, NRF_RTC_TASK_STOP); + nrf_rtc_event_disable(rtc_reg, 0xFFFFFFFF); + nrf_rtc_int_disable(rtc_reg, 0xFFFFFFFF); +} +#endif + +static void nrf_cleanup_clock(void) +{ + nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); +} + +void nrf_cleanup_peripheral(void) +{ +#if defined(NRF_RTC0) + nrf_cleanup_rtc(NRF_RTC0); +#endif +#if defined(NRF_RTC1) + nrf_cleanup_rtc(NRF_RTC1); +#endif +#if defined(NRF_RTC2) + nrf_cleanup_rtc(NRF_RTC2); +#endif +#if defined(NRF_UARTE0) + nrf_uarte_disable(NRF_UARTE0); + nrf_uarte_int_disable(NRF_UARTE0, 0xFFFFFFFF); +#if defined(NRF_DPPIC) + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); +#endif +#endif +#if defined(NRF_UARTE1) + nrf_uarte_disable(NRF_UARTE1); + nrf_uarte_int_disable(NRF_UARTE1, 0xFFFFFFFF); +#if defined(NRF_DPPIC) + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); +#endif +#endif +#if defined(NRF_PPI) + nrf_ppi_channels_disable_all(NRF_PPI); +#endif +#if defined(NRF_DPPIC) + nrf_dppi_channels_disable_all(NRF_DPPIC); +#endif + nrf_cleanup_clock(); +} From cc6103b060affb7ff3b3954aea828efe8111119a Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Fri, 6 Jan 2023 12:24:48 +0100 Subject: [PATCH 014/238] [nrf noup] zephyr: Clean up non-secure RAM if enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To ensure that MCUBoot does not leak keys or other material through memory to non-secure side we clear the memory before jumping to the next image. Signed-off-by: Sigvart Hovland Signed-off-by: Dominik Ermel Signed-off-by: Ole Sæther (cherry picked from commit 047d463df16e048e4f85283bf57b7228c62ff17b) --- boot/zephyr/CMakeLists.txt | 2 +- boot/zephyr/include/nrf_cleanup.h | 5 +++++ boot/zephyr/main.c | 5 ++++- boot/zephyr/nrf_cleanup.c | 13 +++++++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 4716f8932..7b3d1803b 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -530,7 +530,7 @@ if(SYSBUILD) set(mcuboot_image_upgrade_footer_size ${required_upgrade_size} CACHE INTERNAL "Estimated MCUboot update image trailer size" FORCE) endif() -if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL) +if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL OR CONFIG_MCUBOOT_CLEANUP_NONSECURE_RAM) zephyr_library_sources( ${BOOT_DIR}/zephyr/nrf_cleanup.c ) diff --git a/boot/zephyr/include/nrf_cleanup.h b/boot/zephyr/include/nrf_cleanup.h index 6b04cedfe..9e87e13f5 100644 --- a/boot/zephyr/include/nrf_cleanup.h +++ b/boot/zephyr/include/nrf_cleanup.h @@ -16,4 +16,9 @@ */ void nrf_cleanup_peripheral(void); +/** + * Perform cleanup of non-secure RAM that may have been used by MCUBoot. + */ +void nrf_cleanup_ns_ram(void); + #endif diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index cd4e6cb46..13e3b69c1 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -142,7 +142,7 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); #include #endif -#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL +#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL || CONFIG_MCUBOOT_NRF_CLEANUP_NONSECURE_RAM #include #endif @@ -219,6 +219,9 @@ static void do_boot(struct boot_rsp *rsp) #if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL nrf_cleanup_peripheral(); #endif +#if CONFIG_MCUBOOT_NRF_CLEANUP_NONSECURE_RAM && defined(PM_SRAM_NONSECURE_NAME) + nrf_cleanup_ns_ram(); +#endif #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 5bab26b24..2165159ea 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -20,6 +20,10 @@ #include +#if USE_PARTITION_MANAGER +#include +#endif + #define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) #define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ NRF_UARTE_SUBSCRIBE_CONF_OFFS) @@ -81,3 +85,12 @@ void nrf_cleanup_peripheral(void) #endif nrf_cleanup_clock(); } + +#if USE_PARTITION_MANAGER \ + && defined(CONFIG_ARM_TRUSTZONE_M) \ + && defined(PM_SRAM_NONSECURE_NAME) +void nrf_cleanup_ns_ram(void) +{ + memset((void *) PM_SRAM_NONSECURE_ADDRESS, 0, PM_SRAM_NONSECURE_SIZE); +} +#endif From a3d07726648f14d933a2039c20e007addb2a6381 Mon Sep 17 00:00:00 2001 From: Christian Taedcke Date: Thu, 10 Feb 2022 15:37:49 +0100 Subject: [PATCH 015/238] [nrf noup] loader: Fix reading reset addr to support ext flash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When mcuboot_secondary is on external flash, the image header cannot dircetly be accessed via secondary_fa->fa_off. Instead the provided function boot_img_hdr() is used now. Additionally a similar issue is present when trying to read the address of the reset handler. For this flash_area_read() is used now. With this patch is possible to have the update partiton mcuboot_secondary on external flash and update a updatable bootloader (mcuboot) in s0 and/or s1. Signed-off-by: Christian Taedcke Signed-off-by: Ole Sæther Signed-off-by: Sigvart Hovland Signed-off-by: Dominik Ermel (cherry picked from commit 2dac63a3ecd987c056351e09bdb240c3af37ecfe) --- boot/bootutil/src/loader.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 568c28e45..06e16d686 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1174,10 +1174,9 @@ boot_validated_swap_type(struct boot_loader_state *state, #if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) const struct flash_area *secondary_fa = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; - uint32_t vtable_addr = 0; - uint32_t *vtable = 0; + struct image_header *hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); uint32_t reset_addr = 0; + int rc = 0; /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other * B1 slot S0 or S1) share the same secondary slot, we need to check * whether the update candidate in the secondary slot is intended for @@ -1187,16 +1186,19 @@ boot_validated_swap_type(struct boot_loader_state *state, */ if (hdr->ih_magic == IMAGE_MAGIC) { - vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - vtable = (uint32_t *)(vtable_addr); - reset_addr = vtable[1]; + rc = flash_area_read(secondary_fa, hdr->ih_hdr_size + + sizeof(uint32_t), &reset_addr, + sizeof(reset_addr)); + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS if(reset_addr < PM_CPUNET_B0N_ADDRESS) #endif { const struct flash_area *primary_fa; - int rc = flash_area_open(flash_area_id_from_multi_image_slot( + rc = flash_area_open(flash_area_id_from_multi_image_slot( BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT), &primary_fa); @@ -1232,16 +1234,19 @@ boot_validated_swap_type(struct boot_loader_state *state, upgrade_valid = true; } -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) \ + && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) /* If the update is valid, and it targets the network core: perform the * update and indicate to the caller of this function that no update is * available */ if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { + struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; + uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr); uint32_t fw_size = hdr->ih_img_size; - BOOT_LOG_INF("Starting network core update"); - int rc = pcd_network_core_update(vtable, fw_size); + rc = pcd_network_core_update(net_core_fw_addr, fw_size); if (rc != 0) { swap_type = BOOT_SWAP_TYPE_FAIL; From 6f1ba9169c74458cb5bc9985277e228479cc6c63 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 11 Jul 2023 08:42:49 +0100 Subject: [PATCH 016/238] [nrf noup] zephyr: Fix path variables Fixes path variables to use the proper Zephyr module variables Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit c28fa1d8c6d4d5a73b08394f0e96f7cb2f3e3d8f) --- boot/zephyr/CMakeLists.txt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 7b3d1803b..2fd13e9e8 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -27,21 +27,20 @@ assert_exists(FIAT_DIR) # Path to mbed-tls' asn1 parser library. set(MBEDTLS_ASN1_DIR "${MCUBOOT_DIR}/ext/mbedtls-asn1") assert_exists(MBEDTLS_ASN1_DIR) -set(NRF_DIR "${MCUBOOT_DIR}/ext/nrf") +set(MCUBOOT_NRF_EXT_DIR "${MCUBOOT_DIR}/ext/nrf") if(CONFIG_BOOT_USE_NRF_CC310_BL) -set(NRFXLIB_DIR ${ZEPHYR_BASE}/../nrfxlib) -if(NOT EXISTS ${NRFXLIB_DIR}) - message(FATAL_ERROR " + if(NOT EXISTS ${ZEPHYR_NRFXLIB_MODULE_DIR}) + message(FATAL_ERROR " ------------------------------------------------------------------------ - No such file or directory: ${NRFXLIB_DIR} + No such file or directory: ${ZEPHYR_NRFXLIB_MODULE_DIR} The current configuration enables nRF CC310 crypto accelerator hardware with the `CONFIG_BOOT_USE_NRF_CC310_BL` option. Please follow `ext/nrf/README.md` guide to fix your setup or use tinycrypt instead of the HW accelerator. To use the tinycrypt set `CONFIG_BOOT_ECDSA_TINYCRYPT` to y. ------------------------------------------------------------------------") -endif() + endif() endif() zephyr_library_include_directories( @@ -169,8 +168,8 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) ${TINYCRYPT_DIR}/source/utils.c ) elseif(CONFIG_BOOT_USE_NRF_CC310_BL) - zephyr_library_sources(${NRF_DIR}/cc310_glue.c) - zephyr_library_include_directories(${NRF_DIR}) + zephyr_library_sources(${MCUBOOT_NRF_EXT_DIR}/cc310_glue.c) + zephyr_library_include_directories(${MCUBOOT_NRF_EXT_DIR}) zephyr_link_libraries(nrfxlib_crypto) elseif(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) zephyr_include_directories(${BL_CRYPTO_DIR}/../include) From 5fe56c9acdb8ff31788aa89f42673d43e0197639 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 22 Sep 2023 21:31:08 +0000 Subject: [PATCH 017/238] [nrf noup] loader: Do not check reset vector for XIP image The XIP image, 2, does not have reset vector. Signed-off-by: Dominik Ermel (cherry picked from commit d798de3f27589d640a750d98aca4e91affbf927b) --- boot/bootutil/src/loader.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 06e16d686..bafcfefc7 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1057,6 +1057,16 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * overwriting an application written to the incorrect slot. * This feature is only supported by ARM platforms. */ +#if MCUBOOT_IMAGE_NUMBER >= 3 + /* Currently the MCUboot can be configured for up to 3 image, where image number 2 is + * designated for XIP, where it is the second part of image stored in slots of image + * 0. This part of image is not bootable, as the XIP setup is done by the app in + * image 0 slot, and it does not carry the reset vector. + */ + if (area_id == FLASH_AREA_IMAGE_SECONDARY(2)) { + goto out; + } +#endif if (area_id == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) { const struct flash_area *pri_fa = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); struct image_header *secondary_hdr = boot_img_hdr(state, slot); From 33effae0cce49991dfbd3ec4526f65ac305ae8dd Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 18 Sep 2023 13:47:00 +0100 Subject: [PATCH 018/238] [nrf noup] zephyr: Add RAM flash configuration to cache for sysbuild Puts the flash simulation configurtion into cache variables that can be used by other applications and CMake code to know specifics on the simulated flash details Signed-off-by: Jamie McCrae (cherry picked from commit af27205c904fa5eee91eb3a9cec3a1eea939b4aa) --- boot/zephyr/CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 2fd13e9e8..387623dae 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -534,3 +534,14 @@ zephyr_library_sources( ${BOOT_DIR}/zephyr/nrf_cleanup.c ) endif() + +if(SYSBUILD AND CONFIG_PCD_APP) + # Sysbuild requires details of the RAM flash device are stored to the cache of MCUboot so + # that they can be read when running partition manager + dt_nodelabel(ram_flash_dev NODELABEL flash_sim0) + dt_reg_addr(ram_flash_addr PATH ${ram_flash_dev}) + dt_reg_size(ram_flash_size PATH ${ram_flash_dev}) + + set(RAM_FLASH_ADDR "${ram_flash_addr}" CACHE STRING "" FORCE) + set(RAM_FLASH_SIZE "${ram_flash_size}" CACHE STRING "" FORCE) +endif() From 62b5dc1c03be60da3456775b11f08a23c6cbb4bb Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Tue, 17 Oct 2023 11:28:09 +0200 Subject: [PATCH 019/238] [nrf noup] zephyr: Boot even if EXT_ABI is not provided This removes the `return;` to ensure that the application is booted even if EXT_ABI is not provided to the application because it does not include `FW_INFO`. Added a bit more description to the error messages when FW_INFO is not found and EXT_ABI is not able to be provided to the next image. Ref. NCSDK-24132 Signed-off-by: Sigvart Hovland (cherry picked from commit 41cc274e70465192a973b28ca9463c22e3ae9e82) --- boot/zephyr/main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 13e3b69c1..b265481ae 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -206,13 +206,16 @@ static void do_boot(struct boot_rsp *rsp) #endif #if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - bool provided = fw_info_ext_api_provide(fw_info_find((uint32_t)vt), true); + const struct fw_info *firmware_info = fw_info_find((uint32_t) vt); + bool provided = fw_info_ext_api_provide(firmware_info, true); #ifdef PM_S0_ADDRESS /* Only fail if the immutable bootloader is present. */ if (!provided) { - BOOT_LOG_ERR("Failed to provide EXT_APIs\n"); - return; + if (firmware_info == NULL) { + BOOT_LOG_WRN("Unable to find firmware info structure in %p", vt); + } + BOOT_LOG_ERR("Failed to provide EXT_APIs to %p", vt); } #endif #endif From b0457784952ec666d86e9f9c9ae83341dc1c0bf4 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Wed, 27 Sep 2023 15:18:04 +0200 Subject: [PATCH 020/238] =?UTF-8?q?[nrf=20noup]=C2=A0loader:=20Add=20firmw?= =?UTF-8?q?are=20version=20check=20downgrade=20prevention?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For nRF53, the only existing version number metadata is stored in the `firmware_info` structure in the network core. This utilizes PCD to read out the version number and compares it against the version number found in the secondary slot for the network core. Ref. NCSDK-21379 Signed-off-by: Sigvart Hovland (cherry picked from commit 8e91ec1b9ea30ba0ca201bf8fb8cdf173f1188e7) --- boot/bootutil/src/loader.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index bafcfefc7..749d93570 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -51,6 +51,10 @@ #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) #include +#ifdef CONFIG_PCD_READ_NETCORE_APP_VERSION +#include +int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); +#endif #endif #ifdef MCUBOOT_ENC_IMAGES @@ -1016,9 +1020,21 @@ boot_validate_slot(struct boot_loader_state *state, int slot, #if defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION) if (slot != BOOT_PRIMARY_SLOT) { /* Check if version of secondary slot is sufficient */ - rc = boot_version_cmp( - &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, - &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); + +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) \ + && defined(CONFIG_PCD_APP) && defined(CONFIG_PCD_READ_NETCORE_APP_VERSION) + if (BOOT_CURR_IMG(state) == 1) { + rc = pcd_version_cmp_net(fap, boot_img_hdr(state, BOOT_SECONDARY_SLOT)); + } else { + rc = boot_version_cmp( + &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, + &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); + } +#else + rc = boot_version_cmp( + &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, + &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); +#endif if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) { BOOT_LOG_ERR("insufficient version in secondary slot"); flash_area_erase(fap, 0, flash_area_get_size(fap)); From 737742172f400320182e620b8ec2da8cf7d491b8 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Mon, 9 Oct 2023 09:55:57 +0200 Subject: [PATCH 021/238] [nrf noup] boards: thingy53: disable GPIO ISR support Change disables GPIO interrupt support in Zephyr GPIO driver, which is not obligatory for MCUboot. This is needed to reduce memory footprint. Signed-off-by: Nikodem Kastelik (cherry picked from commit 86af2de75205ec5f2c846a2393934360de22fde4) --- boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf index 7d3bc0bec..e10656678 100644 --- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf @@ -21,6 +21,7 @@ CONFIG_UART_LINE_CTRL=y # MCUBoot serial CONFIG_GPIO=y +CONFIG_GPIO_NRFX_INTERRUPT=n CONFIG_MCUBOOT_SERIAL=y CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y CONFIG_BOOT_SERIAL_CDC_ACM=y From 0fcc1f8f5f6d94d49de722c745fd57b9a76c32e8 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 11 Apr 2024 17:26:50 +0200 Subject: [PATCH 022/238] [nrf noup] boot/zephyr/boards: nRF54l15pdk ext flash cfg Added configuration which allows to build MCUboot for nrf54l15pdk_nrf54l15_cpuapp with external flash used for the secondary slot. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 78bc87c46a9501cacd57003271968a554d30e0ee) --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf | 8 ++++++++ .../nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 10 ++++++++++ 2 files changed, 18 insertions(+) create mode 100644 boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf create mode 100644 boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf new file mode 100644 index 000000000..841922dbd --- /dev/null +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf @@ -0,0 +1,8 @@ +CONFIG_MULTITHREADING=y +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_FLASH=y +CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 +CONFIG_MAIN_STACK_SIZE=20480 +CONFIG_BOOT_MAX_IMG_SECTORS=512 +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay new file mode 100644 index 000000000..2341ffd26 --- /dev/null +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -0,0 +1,10 @@ +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; + + +&mx25r64 { + status = "okay"; +}; From 843ee8e437ba50d99cc5490a9c46024f8bddf242 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Tue, 30 Mar 2021 22:45:17 +0200 Subject: [PATCH 023/238] [nrf noup] loader: work-around for multi-image builds Seems multi-image dependencies are not supported for multi-image in NCS yet. This is a workaround which reverts some lines to restore previous MCUboot behavior, so that Immutable bootloader + MCUBoot type builds will work. Ref. NCSDK-8681 Signed-off-by: Sigvart Hovland (cherry picked from commit 4ce3844d5fb9a1b0f90b2f95461f23cdba3e9080) --- boot/bootutil/src/loader.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 749d93570..0454bbd3d 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -402,7 +402,7 @@ boot_verify_dependencies(struct boot_loader_state *state) if (rc == 0) { /* All dependencies've been satisfied, continue with next image. */ BOOT_CURR_IMG(state)++; - } else { + } else if (rc == BOOT_EBADIMAGE) { /* Cannot upgrade due to non-met dependencies, so disable all * image upgrades. */ @@ -411,7 +411,10 @@ boot_verify_dependencies(struct boot_loader_state *state) BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE; } break; - } + } else { + /* Other error happened, images are inconsistent */ + return rc; + } } return rc; } @@ -1755,7 +1758,6 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) } #endif - /** * Performs a clean (not aborted) image update. * From f15d38432b3e86f4a9a43e95a686041523ca5419 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 31 Aug 2023 08:58:31 +0100 Subject: [PATCH 024/238] [nrf noup] loader: Fix missing PCD define check Fixes a missing PCD define check, an image might have the network core partition layout set but if PCD support is not enabled then it should not assume that PCD support is part of mcuboot. Signed-off-by: Jamie McCrae (cherry picked from commit 150a1d473c46e31be583e568348f1303be90cfad) --- boot/bootutil/src/loader.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 0454bbd3d..200a3e8e8 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1264,7 +1264,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) \ - && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) && defined(CONFIG_PCD_APP) /* If the update is valid, and it targets the network core: perform the * update and indicate to the caller of this function that no update is * available @@ -1292,7 +1292,8 @@ boot_validated_swap_type(struct boot_loader_state *state, swap_type = BOOT_SWAP_TYPE_NONE; } } -#endif /* CONFIG_SOC_NRF5340_CPUAPP */ +#endif /* CONFIG_SOC_NRF5340_CPUAPP && PM_CPUNET_B0N_ADDRESS && + !CONFIG_NRF53_MULTI_IMAGE_UPDATE && CONFIG_PCD_APP */ } return swap_type; From ce42cace17415ee62d1743e77bdbb3fbe6edc2f0 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Wed, 31 May 2023 14:41:13 +0200 Subject: [PATCH 025/238] [nrf noup] boot: Add support for NSIB and multi-image This adds support for using both NSIB and the multi-image configuration in MCUboot. Before this was not possible due to upgradable bootloader support through NSIB was using the `UPDATEABLE_IMAGE_NUMBER` configuration to update the updateable bootloader. In this commit we change from using `FLASH_AREA_IMAGE_PRIMARY` to get the flash area ID to using the bootloader state where we set the flash area ID of the free updatable bootloader slot if the image is intended for this slot. Ref. NCSDK-19223 Ref. NCSDK-23305 Signed-off-by: Sigvart Hovland (cherry picked from commit 3ec508400ba3a7d3e5e5bc73e7d4efa78b3375eb) --- boot/bootutil/src/loader.c | 44 +++++++++++++++++++------ boot/zephyr/include/sysflash/sysflash.h | 19 +++++++++-- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 200a3e8e8..a2c6ee5bd 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1108,6 +1108,11 @@ boot_validate_slot(struct boot_loader_state *state, int slot, if (BOOT_CURR_IMG(state) == 1) { min_addr = PM_CPUNET_APP_ADDRESS; max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; +#ifdef PM_S1_ADDRESS + } else if (BOOT_CURR_IMG(state) == 0) { + min_addr = PM_S0_ADDRESS; + max_addr = pri_fa->fa_off + pri_fa->fa_size; +#endif } else #endif { @@ -1228,18 +1233,37 @@ boot_validated_swap_type(struct boot_loader_state *state, { const struct flash_area *primary_fa; rc = flash_area_open(flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), - BOOT_PRIMARY_SLOT), - &primary_fa); - + BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT), + &primary_fa); if (rc != 0) { return BOOT_SWAP_TYPE_FAIL; } - /* Get start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off || - reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for this image - */ + + /* Check start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off) { +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + const struct flash_area *nsib_fa; + + /* NSIB upgrade slot */ + rc = flash_area_open((uint32_t)_image_1_primary_slot_id, + &nsib_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + + /* Image is placed before Primary and within the NSIB slot */ + if (reset_addr > nsib_fa->fa_off + && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { + /* Set primary to be NSIB upgrade slot */ + BOOT_IMG_AREA(state, 0) = nsib_fa; + } +#else + return BOOT_SWAP_TYPE_NONE; +#endif + + } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for any */ return BOOT_SWAP_TYPE_NONE; } } @@ -1503,7 +1527,7 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) BOOT_LOG_INF("Image %d upgrade secondary slot -> primary slot", image_index); BOOT_LOG_INF("Erasing the primary slot"); - rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), + rc = flash_area_open(flash_area_get_id(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)), &fap_primary_slot); assert (rc == 0); diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index b98e48bce..8b47a32b5 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -23,9 +23,24 @@ /* If B0 is present then two bootloaders are present, and we must use * a single secondary slot for both primary slots. */ -#ifdef PM_B0_ADDRESS - +#if defined(PM_B0_ADDRESS) extern uint32_t _image_1_primary_slot_id[]; +#endif +#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) +#elif defined(PM_B0_ADDRESS) #define FLASH_AREA_IMAGE_PRIMARY(x) \ ((x == 0) ? \ From 6cecb1c14aa4e934e12fd00fdc68e6ee2fdbef78 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 10 Aug 2023 17:32:48 +0000 Subject: [PATCH 026/238] [nrf noup] sysflash: Move partition manager definitions to pm_sysflash.h Making sysflash.h and pm_sysflash.h more readable. Signed-off-by: Dominik Ermel (cherry picked from commit 51b7a3f1839d909cf0eeabdee72d3a92ff4a304a) --- boot/zephyr/include/sysflash/pm_sysflash.h | 92 ++++++++++++++++++++++ boot/zephyr/include/sysflash/sysflash.h | 90 ++------------------- 2 files changed, 97 insertions(+), 85 deletions(-) create mode 100644 boot/zephyr/include/sysflash/pm_sysflash.h diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h new file mode 100644 index 000000000..377291e8b --- /dev/null +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef __PM_SYSFLASH_H__ +#define __PM_SYSFLASH_H__ +/* Blocking the __SYSFLASH_H__ */ +#define __SYSFLASH_H__ + +#include +#include + +#ifndef CONFIG_SINGLE_APPLICATION_SLOT + +#if (MCUBOOT_IMAGE_NUMBER == 1) + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID + +#elif (MCUBOOT_IMAGE_NUMBER == 2) + +/* If B0 is present then two bootloaders are present, and we must use + * a single secondary slot for both primary slots. + */ +#if defined(PM_B0_ADDRESS) +extern uint32_t _image_1_primary_slot_id[]; +#endif +#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) +#elif defined(PM_B0_ADDRESS) + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + (uint32_t)_image_1_primary_slot_id : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + 255 ) +#else + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) + +#endif /* PM_B0_ADDRESS */ + +#endif +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID + +#else /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID +/* NOTE: Scratch parition is not used by single image DFU but some of + * functions in common files reference it, so the definitions has been + * provided to allow compilation of common units. + */ +#define FLASH_AREA_IMAGE_SCRATCH 0 + +#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#endif /* __PM_SYSFLASH_H__ */ diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 8b47a32b5..f231c3d02 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -4,93 +4,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __SYSFLASH_H__ -#define __SYSFLASH_H__ - #if USE_PARTITION_MANAGER -#include -#include - -#ifndef CONFIG_SINGLE_APPLICATION_SLOT - -#if (MCUBOOT_IMAGE_NUMBER == 1) - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID - -#elif (MCUBOOT_IMAGE_NUMBER == 2) - -/* If B0 is present then two bootloaders are present, and we must use - * a single secondary slot for both primary slots. - */ -#if defined(PM_B0_ADDRESS) -extern uint32_t _image_1_primary_slot_id[]; -#endif -#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) -#elif defined(PM_B0_ADDRESS) - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - (uint32_t)_image_1_primary_slot_id : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - 255 ) -#else - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) - -#endif /* PM_B0_ADDRESS */ - +/* Blocking the rest of the file */ +#define __SYSFLASH_H__ +#include #endif -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID - -#else /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID -/* NOTE: Scratch parition is not used by single image DFU but some of - * functions in common files reference it, so the definitions has been - * provided to allow compilation of common units. - */ -#define FLASH_AREA_IMAGE_SCRATCH 0 -#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#else +#ifndef __SYSFLASH_H__ +#define __SYSFLASH_H__ -#include #include #include #include @@ -149,6 +71,4 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ -#endif /* USE_PARTITION_MANAGER */ - #endif /* __SYSFLASH_H__ */ From d2d11bf027a180f68447450a7b8615bc35ca016c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 11 Aug 2023 12:29:13 +0000 Subject: [PATCH 027/238] [nrf noup] sysflash: Add support for three images The commit modifies pm_sysflash.h to add support for three application images. Ref. NCSDK-19223 Signed-off-by: Dominik Ermel Signed-off-by: Sigvart Hovland (cherry picked from commit 9c673510b53a4b2c531d565ed98201d4bbbbfb07) --- boot/zephyr/include/sysflash/pm_sysflash.h | 82 ++++++++++++---------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h index 377291e8b..db60ddd03 100644 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -11,37 +11,19 @@ #include #include +#include #ifndef CONFIG_SINGLE_APPLICATION_SLOT -#if (MCUBOOT_IMAGE_NUMBER == 1) - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID - -#elif (MCUBOOT_IMAGE_NUMBER == 2) - +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) /* If B0 is present then two bootloaders are present, and we must use * a single secondary slot for both primary slots. */ -#if defined(PM_B0_ADDRESS) extern uint32_t _image_1_primary_slot_id[]; -#endif -#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) +#endif /* (MCUBOOT_IMAGE_NUMBER == 2 && defined(PM_B0_ADDRESS) */ -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) -#elif defined(PM_B0_ADDRESS) +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) #define FLASH_AREA_IMAGE_PRIMARY(x) \ ((x == 0) ? \ @@ -56,26 +38,52 @@ extern uint32_t _image_1_primary_slot_id[]; (x == 1) ? \ PM_MCUBOOT_SECONDARY_ID: \ 255 ) + +#else /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + */ + +/* Each pair of slots is separated by , and there is no terminating character */ +#define FLASH_AREA_IMAGE_0_SLOTS PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID +#define FLASH_AREA_IMAGE_1_SLOTS PM_MCUBOOT_PRIMARY_1_ID, PM_MCUBOOT_SECONDARY_1_ID +#define FLASH_AREA_IMAGE_2_SLOTS PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID + +#if (MCUBOOT_IMAGE_NUMBER == 1) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS +#elif (MCUBOOT_IMAGE_NUMBER == 2) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ + FLASH_AREA_IMAGE_1_SLOTS +#elif (MCUBOOT_IMAGE_NUMBER == 3) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ + FLASH_AREA_IMAGE_1_SLOTS, \ + FLASH_AREA_IMAGE_2_SLOTS #else +#error Unsupported number of images +#endif -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) +static inline uint32_t __flash_area_ids_for_slot(int img, int slot) +{ + static const int all_slots[] = { + ALL_AVAILABLE_SLOTS + }; + return all_slots[img * 2 + slot]; +}; -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) +#undef FLASH_AREA_IMAGE_0_SLOTS +#undef FLASH_AREA_IMAGE_1_SLOTS +#undef FLASH_AREA_IMAGE_2_SLOTS +#undef ALL_AVAILABLE_SLOTS -#endif /* PM_B0_ADDRESS */ +#define FLASH_AREA_IMAGE_PRIMARY(x) __flash_area_ids_for_slot(x, 0) +#define FLASH_AREA_IMAGE_SECONDARY(x) __flash_area_ids_for_slot(x, 1) +#if !defined(CONFIG_BOOT_SWAP_USING_MOVE) +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID #endif -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID + +#endif /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + */ #else /* CONFIG_SINGLE_APPLICATION_SLOT */ From ee67c04d98ffc8b45140e76164499c9de31f77f0 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 15 Feb 2024 16:47:25 +0100 Subject: [PATCH 028/238] [nrf noup] loader: introduced cleanup of unusable secondary slot Added procedure which clean-up content of all the secondary slot which contains valid header but couldn't be assigned to any of supported primary images. This behavior is needed when configuration allows to use one secondary slot for collecting image for multiple primary slots. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 8f4b472b810dbe0a6fda02d2856efa42985bea09) --- boot/bootutil/src/loader.c | 90 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index a2c6ee5bd..3b34b4b76 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1188,6 +1188,87 @@ boot_update_security_counter(uint8_t image_index, int slot, } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ +#if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ +(defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP)) + +#define SEC_SLOT_VIRGIN 0 +#define SEC_SLOT_TOUCHED 1 +#define SEC_SLOT_ASSIGNED 2 + +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +/* This configuration is peculiar - the one physical secondary slot is + * mocking two logical secondary + */ +#define SEC_SLOT_PHYSICAL_CNT 1 +#else +#define SEC_SLOT_PHYSICAL_CNT MCUBOOT_IMAGE_NUMBER +#endif + +static uint8_t sec_slot_assignmnet[SEC_SLOT_PHYSICAL_CNT] = {0}; + +static inline void sec_slot_touch(struct boot_loader_state *state) +{ + uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); + + if (SEC_SLOT_VIRGIN == sec_slot_assignmnet[idx]) { + sec_slot_assignmnet[idx] = SEC_SLOT_TOUCHED; + } +} + +static inline void sec_slot_mark_assigned(struct boot_loader_state *state) +{ + uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); + + sec_slot_assignmnet[idx] = SEC_SLOT_ASSIGNED; +} + +/** + * Cleanu up all secondary slot which couldn't be assigned to any primary slot. + * + * This function erases content of each secondary slot which contains valid + * header but couldn't be assigned to any of supported primary images. + * + * This function is supposed to be called after boot_validated_swap_type() + * iterates over all the images in context_boot_go(). + */ +static void sec_slot_cleanup_if_unusable(void) +{ + uint8_t idx; + + for (idx = 0; idx < SEC_SLOT_PHYSICAL_CNT; idx++) { + if (SEC_SLOT_TOUCHED == sec_slot_assignmnet[idx]) { + const struct flash_area *secondary_fa; + int rc; + + rc = flash_area_open(flash_area_id_from_multi_image_slot(idx, BOOT_SECONDARY_SLOT), + &secondary_fa); + if (!rc) { + rc = flash_area_erase(secondary_fa, 0, secondary_fa->fa_size); + if (!rc) { + BOOT_LOG_ERR("Cleaned-up secondary slot of %d. image.", idx); + } + } + + if (rc) { + BOOT_LOG_ERR("Can not cleanup secondary slot of %d. image.", idx); + } + } + } +} +#else +static inline void sec_slot_touch(struct boot_loader_state *state) +{ +} +static inline void sec_slot_mark_assigned(struct boot_loader_state *state) +{ +} +static inline void sec_slot_cleanup_if_unusable(void) +{ +} +#endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ + defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */ + #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) /** * Determines which swap operation to perform, if any. If it is determined @@ -1226,6 +1307,9 @@ boot_validated_swap_type(struct boot_loader_state *state, if (rc != 0) { return BOOT_SWAP_TYPE_FAIL; } + + sec_slot_touch(state); + #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS if(reset_addr < PM_CPUNET_B0N_ADDRESS) @@ -1260,6 +1344,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } #else return BOOT_SWAP_TYPE_NONE; + #endif } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { @@ -1268,7 +1353,9 @@ boot_validated_swap_type(struct boot_loader_state *state, } } #endif /* PM_S1_ADDRESS */ + sec_slot_mark_assigned(state); } + #endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); @@ -2329,6 +2416,9 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } } + /* cleanup secondary slots which were recognized unusable*/ + sec_slot_cleanup_if_unusable(); + #if (BOOT_IMAGE_NUMBER > 1) if (has_upgrade) { /* Iterate over all the images and verify whether the image dependencies From ec59c38081d5b11fb00263a43981ba3756b28138 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Tue, 16 Apr 2024 16:10:55 +0200 Subject: [PATCH 029/238] [nrf noup] boards: nrf54l15: Disable FPROTECT FPROTECT is not suppored yet for nrf54l15. Signed-off-by: Grzegorz Chwierut Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 0b5810de95eb93bbd4fba8e20a2152b33880fc43) --- boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf index 33e7e6124..03ad533f9 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -7,4 +7,7 @@ CONFIG_BOOT_MAX_IMG_SECTORS=256 # Ensure that the qspi driver is disabled by default CONFIG_NORDIC_QSPI_NOR=n +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + CONFIG_BOOT_WATCHDOG_FEED=n From 3853d2664de779eaa3300a37a51628bf9c9f2513 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Fri, 17 May 2024 18:25:07 +0200 Subject: [PATCH 030/238] [nrf noup] loader: remove cleanup for direct xip mode Move ifdefs just to not add code for cleanup unusable slot when direct xip mode is enabled to avoid warnings. Signed-off-by: Grzegorz Chwierut (cherry picked from commit 650d11c32368d8ddea310fcdf0d52b45d9017f15) --- boot/bootutil/src/loader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 3b34b4b76..9c14c03e6 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1188,6 +1188,8 @@ boot_update_security_counter(uint8_t image_index, int slot, } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ +#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) + #if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ (defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP)) @@ -1269,7 +1271,6 @@ static inline void sec_slot_cleanup_if_unusable(void) #endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */ -#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) /** * Determines which swap operation to perform, if any. If it is determined * that a swap operation is required, the image in the secondary slot is checked From b305c3d7d1514dea26d80c25ea0688a74011830b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 19 Apr 2024 16:33:07 +0000 Subject: [PATCH 031/238] [nrf noup] zephyr: Clean up non-secure RAM if enabled fixup! [nrf noup] zephyr: Clean up non-secure RAM if enabled Add support for nrf54l15 UARTE20 and UARTE30. Signed-off-by: Dominik Ermel (cherry picked from commit 0611b4c3feba6328e09b19f23a879dbc78b5d174) --- boot/zephyr/nrf_cleanup.c | 66 +++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 2165159ea..051705ec9 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -5,9 +5,8 @@ */ #include -#if defined(NRF_UARTE0) || defined(NRF_UARTE1) - #include -#endif +#include +#include #if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) #include #endif @@ -24,6 +23,11 @@ #include #endif +#if defined(NRF_UARTE0) || defined(NRF_UARTE1) || defined(NRF_UARTE20) || \ + defined(NRF_UARTE30) +#define NRF_UARTE_CLEANUP +#endif + #define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) #define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ NRF_UARTE_SUBSCRIBE_CONF_OFFS) @@ -41,6 +45,23 @@ static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) } #endif +#if defined(NRF_UARTE_CLEANUP) +static NRF_UARTE_Type *nrf_uarte_to_clean[] = { +#if defined(NRF_UARTE0) + NRF_UARTE0, +#endif +#if defined(NRF_UARTE1) + NRF_UARTE1, +#endif +#if defined(NRF_UARTE20) + NRF_UARTE20, +#endif +#if defined(NRF_UARTE30) + NRF_UARTE30, +#endif +}; +#endif + static void nrf_cleanup_clock(void) { nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); @@ -57,26 +78,31 @@ void nrf_cleanup_peripheral(void) #if defined(NRF_RTC2) nrf_cleanup_rtc(NRF_RTC2); #endif -#if defined(NRF_UARTE0) - nrf_uarte_disable(NRF_UARTE0); - nrf_uarte_int_disable(NRF_UARTE0, 0xFFFFFFFF); -#if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); -#endif -#endif -#if defined(NRF_UARTE1) - nrf_uarte_disable(NRF_UARTE1); - nrf_uarte_int_disable(NRF_UARTE1, 0xFFFFFFFF); + +#if defined(NRF_UARTE_CLEANUP) + for (int i = 0; i < sizeof(nrf_uarte_to_clean) / sizeof(nrf_uarte_to_clean[0]); ++i) { + NRF_UARTE_Type *current = nrf_uarte_to_clean[i]; + + nrfy_uarte_int_disable(current, 0xFFFFFFFF); + nrfy_uarte_int_uninit(current); + nrfy_uarte_task_trigger(current, NRF_UARTE_TASK_STOPRX); + + nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXSTARTED); + nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_ENDRX); + nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXTO); + nrfy_uarte_disable(current); + #if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)current + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, + NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)current + NRF_UARTE_PUBLISH_CONF_OFFS, 0, + NRF_UARTE_PUBLISH_CONF_SIZE); #endif + } #endif + #if defined(NRF_PPI) nrf_ppi_channels_disable_all(NRF_PPI); #endif From 826a4071ed8458da61d1152530c3a0ba8fda58be Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 15 Apr 2024 18:54:45 +0200 Subject: [PATCH 032/238] [nrf noup] boot/zephyr/boards: nrf54l15pdk ext-flash partition Added DTS with partitioning which involves external flash as place for slo1_partition. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit efe6681e7a6f6b121d5c3c6b40af828fbde9baf7) --- ...54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index 2341ffd26..76b648903 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -4,7 +4,42 @@ }; }; +/delete-node/ &boot_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +/delete-node/ &slot0_ns_partition; +/delete-node/ &slot1_ns_partition; + +/delete-node/ &storage_partition; + +&rram0 { + partitions { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x000000000 0x00014000>; + }; + slot0_partition: partition@14000 { + label = "image-0"; + reg = <0x000014000 0x0015A000>; + }; + storage_partition: partition@16E000 { + label = "storage"; + reg = < 0x16E000 0x9000 >; + }; + }; +}; &mx25r64 { status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + slot1_partition: partition@0 { + label = "image-1"; + reg = <0x000000000 0x0015A000>; + }; + }; }; From 0656a67a1c74658a83e3aca7317b7642310998bd Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 20 May 2024 15:48:33 +0200 Subject: [PATCH 033/238] [nrf noup] boot/zephyr/boards: nrf54l15pdk ext-flash update This patch supplements the configuration for external flash so MCUboot can be build with FILE_SUFFIX="ext_flash" for the nrf54l15pdk instead of explicitly configuration specification. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 3131c92c5109266145fdc0528bf3991d6709a6a6) --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf | 7 +++++++ .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 1 + 2 files changed, 8 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf index 841922dbd..8fc12e074 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf @@ -6,3 +6,10 @@ CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 CONFIG_MAIN_STACK_SIZE=20480 CONFIG_BOOT_MAX_IMG_SECTORS=512 CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +# Ensure that the qspi driver is disabled by default +CONFIG_NORDIC_QSPI_NOR=n + +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + +CONFIG_BOOT_WATCHDOG_FEED=n diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index 76b648903..ea024fcec 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -1,6 +1,7 @@ / { chosen { nordic,pm-ext-flash = &mx25r64; + zephyr,code-partition = &boot_partition; }; }; From 152f6411899b0d0f8b2c1597af476a2471191194 Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Tue, 12 Mar 2024 12:30:52 +0100 Subject: [PATCH 034/238] [nrf noup] boards: thingy91x: enable serial recovery This patch disbales MCUBoot logging and enables serial recovery for the Thingy:91. Signed-off-by: Maximilian Deubel Signed-off-by: Bernt Johan Damslora (cherry picked from commit f67a11a8b4f6fff87641be346c4744ea059bffd7) --- boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf | 10 ++++++++-- boot/zephyr/boards/thingy91x_nrf9151.conf | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf index 72dfa7fca..37c7e95b1 100644 --- a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf @@ -32,7 +32,7 @@ CONFIG_USB_COMPOSITE_DEVICE=y CONFIG_USB_MASS_STORAGE=n CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x520F +CONFIG_USB_DEVICE_PID=0x910A CONFIG_BOOT_SERIAL_BOOT_MODE=y @@ -49,6 +49,12 @@ CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y CONFIG_FLASH_SIMULATOR_STATS=n CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y -CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +# Makes it possible to update the network core using the flash simulator CONFIG_NRF53_RECOVERY_NETWORK_CORE=y + +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y + +# Skip checks on the secondary image to make it possible to update MCUBoot on S1/S0 +CONFIG_MCUBOOT_VERIFY_IMG_ADDRESS=n diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf index 33cd3301c..2efe1e170 100644 --- a/boot/zephyr/boards/thingy91x_nrf9151.conf +++ b/boot/zephyr/boards/thingy91x_nrf9151.conf @@ -6,3 +6,12 @@ CONFIG_SPI_NOR=y CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 CONFIG_SPI_NOR_SFDP_DEVICETREE=y CONFIG_MULTITHREADING=y + +# Disable Zephyr console and use UART for MCUboot serial recovery instead +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n +CONFIG_MCUBOOT_SERIAL=y + +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y From f0a0c50c3d8a4a1ecc0564bc5c56b7454b01ad9d Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 17 May 2024 14:14:54 +0200 Subject: [PATCH 035/238] [nrf noup] boot: zephyr: Disable boot banner if NCS_BOOT_BANNER is used Mcuboot's boot banner should not be used if NCS boot banner is enabled. Signed-off-by: Robert Lubos (cherry picked from commit 7b018cb85202d7d46abcdcd496c7f5d1afa2a2d5) --- boot/zephyr/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 4b134b28f..5f44a109a 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -705,6 +705,7 @@ config BOOT_DISABLE_CACHES config MCUBOOT_BOOT_BANNER bool "Use MCUboot boot banner" depends on BOOT_BANNER + depends on !NCS_BOOT_BANNER depends on "$(APP_VERSION_EXTENDED_STRING)" != "" default y help From f3ae1af0b0777b6bde918d9190bff22ef9ba705f Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 27 May 2024 13:59:49 +0200 Subject: [PATCH 036/238] [nrf noup] boot/zephyr: fix fw_info search By the upstream patch the vt get now the pointer to the copy of the arm_vector instead of original. This patch fixes address of the firmware which is to be taken by the fw_info_find. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 3be724f5537c53b6ba6ef6e6b34cad0f961c50ff) --- boot/zephyr/main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index b265481ae..b4cf43602 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -206,7 +206,14 @@ static void do_boot(struct boot_rsp *rsp) #endif #if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - const struct fw_info *firmware_info = fw_info_find((uint32_t) vt); + uintptr_t fw_start_addr; + + rc = flash_device_base(rsp->br_flash_dev_id, &fw_start_addr); + assert(rc == 0); + + fw_start_addr += rsp->br_image_off + rsp->br_hdr->ih_hdr_size; + + const struct fw_info *firmware_info = fw_info_find(fw_start_addr); bool provided = fw_info_ext_api_provide(firmware_info, true); #ifdef PM_S0_ADDRESS From 0f317a215e16885d744b84ee6bee662846159844 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 28 May 2024 09:31:16 +0000 Subject: [PATCH 037/238] [nrf noup] Revert of zephyr: arm: Update reading the flash image reset vector This is revert of upstream commit 453096b17ddc3aac7bf6afb97c40591d5ea3aa9c which was supposed to allow picking interrupt vector table from flash area but the whole modification unfortunately misunderstood difference between flash device ID and flash area ID. The commit is not important for sdk-nrf and requires re-design and fixing upstream. Signed-off-by: Dominik Ermel (cherry picked from commit f1e1675630561a745d28107144e9a863860204cf) --- boot/zephyr/flash_map_extended.c | 8 ++------ boot/zephyr/main.c | 20 +++++--------------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c index 4631da75b..d0744afbd 100644 --- a/boot/zephyr/flash_map_extended.c +++ b/boot/zephyr/flash_map_extended.c @@ -141,12 +141,8 @@ int flash_area_sector_from_off(off_t off, struct flash_sector *sector) uint8_t flash_area_get_device_id(const struct flash_area *fa) { -#if defined(CONFIG_ARM) - return fa->fa_id; -#else - (void)fa; - return FLASH_DEVICE_ID; -#endif + (void)fa; + return FLASH_DEVICE_ID; } #define ERASED_VAL 0xff diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index b4cf43602..e3347a2fa 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -174,26 +174,16 @@ static void do_boot(struct boot_rsp *rsp) /* Get ram address for image */ vt = (struct arm_vector_table *)(rsp->br_hdr->ih_load_addr + rsp->br_hdr->ih_hdr_size); #else + uintptr_t flash_base; int rc; - const struct flash_area *fap; - static uint32_t dst[2]; /* Jump to flash image */ - rc = flash_area_open(rsp->br_flash_dev_id, &fap); - assert(rc == 0); - - rc = flash_area_read(fap, rsp->br_hdr->ih_hdr_size, dst, sizeof(dst)); + rc = flash_device_base(rsp->br_flash_dev_id, &flash_base); assert(rc == 0); -#ifndef CONFIG_ASSERT - /* Enter a lock up as asserts are disabled */ - if (rc != 0) { - while (1); - } -#endif - - flash_area_close(fap); - vt = (struct arm_vector_table *)dst; + vt = (struct arm_vector_table *)(flash_base + + rsp->br_image_off + + rsp->br_hdr->ih_hdr_size); #endif if (IS_ENABLED(CONFIG_SYSTEM_TIMER_HAS_DISABLE_SUPPORT)) { From cc42516352e797433e6e0413fc41e08d2b583739 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 3 Jun 2024 14:41:59 +0200 Subject: [PATCH 038/238] [nrf noup] zephyr: disabled EXT_API_ATLEAST_OPTIONAL Disabled at last optional EXT_API when external-crypto is enabled. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 1d023039111774334a3bcf85f9d876286ed6cb74) --- boot/zephyr/external_crypto.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/external_crypto.conf b/boot/zephyr/external_crypto.conf index c362f000a..8181ad51c 100644 --- a/boot/zephyr/external_crypto.conf +++ b/boot/zephyr/external_crypto.conf @@ -18,4 +18,3 @@ CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y CONFIG_SB_CRYPTO_CLIENT_SHA256=y CONFIG_BL_SHA256_EXT_API_REQUIRED=y CONFIG_BL_SECP256R1_EXT_API_REQUIRED=y -CONFIG_EXT_API_PROVIDE_EXT_API_ATLEAST_OPTIONAL=y From 4f84ba9bdf6c4a97457e6f74096b83e97ce9ce35 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Wed, 5 Jun 2024 15:46:13 +0200 Subject: [PATCH 039/238] [nrf noup] zephyr/boards: fix nrf54l15pdk ext flash dts overlay Align to changes in DTS: renamed: rram0 -> cpuapp_rram sized up cpauapp_rram region szie as part of it was reserved for cpuflpr_rram (which is not used by this config). Signed-off-by: Andrzej Puzdrowski (cherry picked from commit f1c2b8cb41cbeedbc625fdec7f9f29e91eec0c8d) --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index ea024fcec..60ee6fe51 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -14,7 +14,8 @@ /delete-node/ &storage_partition; -&rram0 { +&cpuapp_rram { + reg = < 0x0 DT_SIZE_K(1524) >; partitions { boot_partition: partition@0 { label = "mcuboot"; From d639f907407e7a36bd1d68fc042946e33d433e23 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 11 Jun 2024 12:32:51 +0100 Subject: [PATCH 040/238] [nrf noup] boot: zephyr: Add NCS boot banner Adds a boot banner which shows as MCUboot Signed-off-by: Jamie McCrae (cherry picked from commit 6869a65c9171849f1c50407b924e875fcc9d6e92) --- boot/zephyr/prj.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 23b5f3b93..e4f7d9030 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -37,3 +37,6 @@ CONFIG_CBPRINTF_NANO=y ### Use the minimal C library to reduce flash usage CONFIG_MINIMAL_LIBC=y CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 + +# NCS boot banner +CONFIG_NCS_APPLICATION_BOOT_BANNER_STRING="MCUboot" From d9fe0115232e5aa06b03de40c6cc91809f224540 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 13 Jun 2024 16:34:55 +0200 Subject: [PATCH 041/238] [nrf noup] boot/../loader: skip downgrade prevention for s1/s0 This patch introduces skip on checking downgrade for s1/s0 upgrade image (chain-loaded by NSIB). which is used for upgrade MCUboot instance itself. Reason is that sdk-mcuboot has not access to semantic version of its own image. I also shouldn't touch HW counter used for hardware downgrade prevention for the application image (which was the case). HW counters for s0/s1 image are owned by NSIB because its role is to prevnt dongrades of s0/s1 MCUboot. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 776ee26039e6aec64b65ee393c93e5cda2d1a7b2) --- boot/bootutil/src/loader.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 9c14c03e6..151944f1b 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -70,6 +70,9 @@ int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); BOOT_LOG_MODULE_DECLARE(mcuboot); static struct boot_loader_state boot_data; +#ifdef PM_S1_ADDRESS +static bool owner_nsib[BOOT_IMAGE_NUMBER] = {false}; +#endif #if (BOOT_IMAGE_NUMBER > 1) #define IMAGES_ITER(x) for ((x) = 0; (x) < BOOT_IMAGE_NUMBER; ++(x)) @@ -1286,6 +1289,9 @@ boot_validated_swap_type(struct boot_loader_state *state, int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); bool upgrade_valid = false; +#if defined(PM_S1_ADDRESS) + owner_nsib[BOOT_CURR_IMG(state)] = false; +#endif #if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) const struct flash_area *secondary_fa = @@ -1342,6 +1348,7 @@ boot_validated_swap_type(struct boot_loader_state *state, && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { /* Set primary to be NSIB upgrade slot */ BOOT_IMG_AREA(state, 0) = nsib_fa; + owner_nsib[BOOT_CURR_IMG(state)] = true; } #else return BOOT_SWAP_TYPE_NONE; @@ -1352,6 +1359,10 @@ boot_validated_swap_type(struct boot_loader_state *state, /* The image in the secondary slot is not intended for any */ return BOOT_SWAP_TYPE_NONE; } + + if ((primary_fa->fa_off == PM_S0_ADDRESS) || (primary_fa->fa_off == PM_S1_ADDRESS)) { + owner_nsib[BOOT_CURR_IMG(state)] = true; + } } #endif /* PM_S1_ADDRESS */ sec_slot_mark_assigned(state); @@ -2291,6 +2302,13 @@ check_downgrade_prevention(struct boot_loader_state *state) uint32_t security_counter[2]; int rc; +#if defined(PM_S1_ADDRESS) + if (owner_nsib[BOOT_CURR_IMG(state)]) { + /* Downgrade prevention on S0/S1 image is managed by NSIB */ + return 0; + } +#endif + if (MCUBOOT_DOWNGRADE_PREVENTION_SECURITY_COUNTER) { /* If there was security no counter in slot 0, allow swap */ rc = bootutil_get_img_security_cnt(&(BOOT_IMG(state, 0).hdr), From daf2946a0f07a14b57bd69d29ac4cdde6f810fb7 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Tue, 18 Jun 2024 17:35:41 +0200 Subject: [PATCH 042/238] [nrf noup] boot/../loader: reboot after updating s0/s1 As this is MCUboot updating itself, it should reboot the device so NSIB will chainload the update MCUboot Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 85419552247489623522d64b605310751becda67) --- boot/bootutil/src/loader.c | 10 ++++++++++ boot/zephyr/Kconfig | 1 + 2 files changed, 11 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 151944f1b..f81bafca7 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,6 +49,10 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" +#ifdef __ZEPHYR__ +#include +#endif + #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) #include #ifdef CONFIG_PCD_READ_NETCORE_APP_VERSION @@ -2506,6 +2510,12 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) rc = boot_perform_update(state, &bs); } assert(rc == 0); +#if defined(PM_S1_ADDRESS) && defined(CONFIG_REBOOT) + if (owner_nsib[BOOT_CURR_IMG(state)]) { + sys_reboot(SYS_REBOOT_COLD); + + } +#endif break; case BOOT_SWAP_TYPE_FAIL: diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 5f44a109a..db2e0e8dc 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -18,6 +18,7 @@ config MCUBOOT select MPU_ALLOW_FLASH_WRITE if ARM_MPU select USE_DT_CODE_PARTITION if HAS_FLASH_LOAD_OFFSET select MCUBOOT_BOOTUTIL_LIB + select REBOOT if SECURE_BOOT config BOOT_USE_MBEDTLS bool From e66169aa8daf93eee0ff3729ecc2c343c7fade51 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 4 Sep 2024 08:07:38 +0100 Subject: [PATCH 043/238] [nrf noup] Remove secure boot debug Kconfig fixup! [nrf noup] zephyr: add 'minimal' configuration files Removes setting a now removed Kconfig option Signed-off-by: Jamie McCrae --- boot/zephyr/prj_minimal.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/prj_minimal.conf b/boot/zephyr/prj_minimal.conf index 1f90e708b..55d4c6167 100644 --- a/boot/zephyr/prj_minimal.conf +++ b/boot/zephyr/prj_minimal.conf @@ -34,7 +34,6 @@ CONFIG_NCS_SAMPLES_DEFAULTS=n CONFIG_NO_RUNTIME_CHECKS=y CONFIG_NRF_RTC_TIMER=n CONFIG_PRINTK=n -CONFIG_SECURE_BOOT_DEBUG=n CONFIG_SERIAL=n CONFIG_SIZE_OPTIMIZATIONS=y CONFIG_SYS_CLOCK_EXISTS=n From 5db198194c10e7a99bad2742e87e8c503b6d2c60 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 29 Aug 2024 12:41:37 +0100 Subject: [PATCH 044/238] [nrf noup] bootutil: loader: Fix netcore address checking Fixes an issues with wrongly checking the network core reset address Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index f81bafca7..41697a010 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1323,7 +1323,7 @@ boot_validated_swap_type(struct boot_loader_state *state, #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS - if(reset_addr < PM_CPUNET_B0N_ADDRESS) + if(!(reset_addr >= PM_CPUNET_APP_ADDRESS && reset_addr < PM_CPUNET_APP_END_ADDRESS)) #endif { const struct flash_area *primary_fa; @@ -1396,7 +1396,8 @@ boot_validated_swap_type(struct boot_loader_state *state, * update and indicate to the caller of this function that no update is * available */ - if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { + if (upgrade_valid && reset_addr >= PM_CPUNET_APP_ADDRESS && + reset_addr < PM_CPUNET_APP_END_ADDRESS) { struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr); From 9ac6f766295fdf9d639782148449f2587bc72a34 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 16 Sep 2024 16:17:36 +0200 Subject: [PATCH 045/238] [nrf fromtree] boot: zephyr: boards: Add nrf54l15dk configuration Adds the configuration for this board Signed-off-by: Jamie McCrae Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 242db1a9301dc21bd6d45351987ee80b48a86790) --- boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf new file mode 100644 index 000000000..43d8cebe3 --- /dev/null +++ b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +# Ensure that the SPI NOR driver is disabled by default +CONFIG_SPI_NOR=n + +CONFIG_BOOT_WATCHDOG_FEED=n From f30dce197f34d4df77d8e66997dff0ce948c2b82 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Wed, 18 Sep 2024 12:28:37 +0200 Subject: [PATCH 046/238] [nrf noup] boards: nrf54l15dk: Disable FPROTECT FPROTECT is not suppored for nrf54l15dk. Signed-off-by: Andrzej Puzdrowski --- boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf index 43d8cebe3..8d8eb845f 100644 --- a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf +++ b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf @@ -7,4 +7,7 @@ CONFIG_BOOT_MAX_IMG_SECTORS=256 # Ensure that the SPI NOR driver is disabled by default CONFIG_SPI_NOR=n +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + CONFIG_BOOT_WATCHDOG_FEED=n From 0c076898551d3053e8b7b115b12650b3f704f4ed Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 22 Aug 2024 10:43:14 +0100 Subject: [PATCH 047/238] [nrf fromtree] bootutil: loader: Add state to boot_is_header_valid() function Adds the state object to this function so it can be referenced Signed-off-by: Jamie McCrae (cherry picked from commit dbb5c782fbfd1dc13f9c273cbcf6935128b44e7a) --- boot/bootutil/src/loader.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 41697a010..08fd0faad 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -880,10 +880,13 @@ split_image_check(struct image_header *app_hdr, * within the flash area we are in. */ static bool -boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fap) +boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fap, + struct boot_loader_state *state) { uint32_t size; + (void)state; + if (hdr->ih_magic != IMAGE_MAGIC) { return false; } @@ -1062,7 +1065,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, { FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs); } - if (!boot_is_header_valid(hdr, fap) || FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { + if (!boot_is_header_valid(hdr, fap, state) || FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { if ((slot != BOOT_PRIMARY_SLOT) || ARE_SLOTS_EQUIVALENT()) { flash_area_erase(fap, 0, flash_area_get_size(fap)); /* Image is invalid, erase it to prevent further unnecessary @@ -2776,7 +2779,7 @@ boot_get_slot_usage(struct boot_loader_state *state) for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) { hdr = boot_img_hdr(state, slot); - if (boot_is_header_valid(hdr, BOOT_IMG_AREA(state, slot))) { + if (boot_is_header_valid(hdr, BOOT_IMG_AREA(state, slot), state)) { state->slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = true; BOOT_LOG_IMAGE_INFO(slot, hdr); } else { From 4e81dcd2d07c6dcce1126f984fdcbfec17574ab6 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 22 Aug 2024 10:44:46 +0100 Subject: [PATCH 048/238] [nrf fromtree] bootutil: loader: Verify image header before checking image Changes the order of operations to validate the image header before checking the image, it does not make sense to check the image if the header itself is invalid Signed-off-by: Jamie McCrae (cherry picked from commit 2939d305456ad24cbc5711220702c07142ad88f3) --- boot/bootutil/src/loader.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 08fd0faad..f1f2777b3 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1059,13 +1059,16 @@ boot_validate_slot(struct boot_loader_state *state, int slot, } } #endif - BOOT_HOOK_CALL_FIH(boot_image_check_hook, FIH_BOOT_HOOK_REGULAR, - fih_rc, BOOT_CURR_IMG(state), slot); - if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR)) - { - FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs); + if (!boot_is_header_valid(hdr, fap, state)) { + fih_rc = FIH_FAILURE; + } else { + BOOT_HOOK_CALL_FIH(boot_image_check_hook, FIH_BOOT_HOOK_REGULAR, + fih_rc, BOOT_CURR_IMG(state), slot); + if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR)) { + FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs); + } } - if (!boot_is_header_valid(hdr, fap, state) || FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { if ((slot != BOOT_PRIMARY_SLOT) || ARE_SLOTS_EQUIVALENT()) { flash_area_erase(fap, 0, flash_area_get_size(fap)); /* Image is invalid, erase it to prevent further unnecessary From 4e74426743a307b47b66cedd4271077856799118 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 22 Aug 2024 10:49:05 +0100 Subject: [PATCH 049/238] [nrf fromtree] docs: release-notes: Add note on bootutil changes Adds notes on the changed bootutil features Signed-off-by: Jamie McCrae (cherry picked from commit bf13555d13a310e5ac6fb68053351ec9b07b9c28) --- docs/release-notes.d/bootutil-image-verification.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs/release-notes.d/bootutil-image-verification.md diff --git a/docs/release-notes.d/bootutil-image-verification.md b/docs/release-notes.d/bootutil-image-verification.md new file mode 100644 index 000000000..a1cc58842 --- /dev/null +++ b/docs/release-notes.d/bootutil-image-verification.md @@ -0,0 +1,4 @@ +- Changed bootutil's order of events to verify the image header + before checking the image. +- Added the bootloader state object to the bootutil + boot_is_header_valid() function From da149891d1d1151a3eaa594da450690b2549b77d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 31 Jul 2024 08:58:15 +0100 Subject: [PATCH 050/238] [nrf fromtree] bootutil: Add compressed image flags and TLV Adds some flags to indicate if the data of an image is compressed (lzma1 and lzma2) and adds new TLVs for compressed images relating to the hash, signature and size of the decompressed image data, this allows the image to be validated before decompressing, then validated after decompression to ensure an image is always valid for a device Signed-off-by: Jamie McCrae (cherry picked from commit 91d86b8a3259ae27bad0a4bd54ddd8a402e0f34a) --- boot/bootutil/include/bootutil/image.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 1f12d9512..3e03f80dd 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -71,6 +71,13 @@ struct flash_area; */ #define IMAGE_F_ROM_FIXED 0x00000100 +/* + * Flags that indicate if the image data is compressed + */ +#define IMAGE_F_COMPRESSED_LZMA1 0x00000200 +#define IMAGE_F_COMPRESSED_LZMA2 0x00000400 +#define IMAGE_F_COMPRESSED_ARM_THUMB_FLT 0x00000800 + /* * ECSDA224 is with NIST P-224 * ECSDA256 is with NIST P-256 @@ -101,6 +108,18 @@ struct flash_area; #define IMAGE_TLV_DEPENDENCY 0x40 /* Image depends on other image */ #define IMAGE_TLV_SEC_CNT 0x50 /* security counter */ #define IMAGE_TLV_BOOT_RECORD 0x60 /* measured boot record */ +/* The following flags relate to compressed images and are for the decompressed image data */ +#define IMAGE_TLV_DECOMP_SIZE 0x70 /* Decompressed image size excluding header/TLVs */ +#define IMAGE_TLV_DECOMP_SHA 0x71 /* + * Decompressed image shaX hash, this field must match + * the format and size of the raw slot (compressed) + * shaX hash + */ +#define IMAGE_TLV_DECOMP_SIGNATURE 0x72 /* + * Decompressed image signature, this field must match + * the format and size of the raw slot (compressed) + * signature + */ /* * vendor reserved TLVs at xxA0-xxFF, * where xx denotes the upper byte @@ -160,6 +179,12 @@ struct image_tlv { #define MUST_DECRYPT(fap, idx, hdr) \ (flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_ENCRYPTED(hdr)) +#define COMPRESSIONFLAGS (IMAGE_F_COMPRESSED_LZMA1 | IMAGE_F_COMPRESSED_LZMA2 \ + | IMAGE_F_COMPRESSED_ARM_THUMB_FLT) +#define IS_COMPRESSED(hdr) ((hdr)->ih_flags & COMPRESSIONFLAGS) +#define MUST_DECOMPRESS(fap, idx, hdr) \ + (flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_COMPRESSED(hdr)) + _Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE, "struct image_header not required size"); From 53722dac8b7eb5bf564abc338fa18f6df9a49679 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 23 Aug 2024 08:13:00 +0100 Subject: [PATCH 051/238] [nrf fromtree] zephyr: Add Kconfig for decompression Adds a Kconfig allowing the decompression option to be selected Signed-off-by: Jamie McCrae (cherry picked from commit 0c1ddf7e23a776309d0de7e5eb94ad50d650953b) --- boot/zephyr/Kconfig | 27 +++++++++++++++++++ .../include/mcuboot_config/mcuboot_config.h | 4 +++ 2 files changed, 31 insertions(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index db2e0e8dc..2dbfc3135 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -721,6 +721,33 @@ config MCUBOOT_BOOT_BANNER config BOOT_BANNER_STRING default "Using Zephyr OS build" if MCUBOOT_BOOT_BANNER +config BOOT_DECOMPRESSION_SUPPORT + bool + help + Hidden symbol which should be selected if a system provided decompression support. + +if BOOT_DECOMPRESSION_SUPPORT + +menuconfig BOOT_DECOMPRESSION + bool "Decompression" + help + If enabled, will include support for compressed images being loaded to the secondary slot + which then get decompressed into the primary slot. This mode allows the secondary slot to + be smaller than primary slot which otherwise would not be allowed. + +if BOOT_DECOMPRESSION + +config BOOT_DECOMPRESSION_BUFFER_SIZE + int "Write buffer size" + range 16 16384 + default 4096 + help + The size of a secondary buffer used for writing decompressed data to the storage device. + +endif # BOOT_DECOMPRESSION + +endif # BOOT_DECOMPRESSION_SUPPORT + endmenu config MCUBOOT_DEVICE_SETTINGS diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 7ef0ae11a..824e83b75 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -126,6 +126,10 @@ #define MCUBOOT_ENCRYPT_X25519 #endif +#ifdef CONFIG_BOOT_DECOMPRESSION +#define MCUBOOT_DECOMPRESS_IMAGES +#endif + #ifdef CONFIG_BOOT_BOOTSTRAP #define MCUBOOT_BOOTSTRAP 1 #endif From 16e15ce40ec4a88f8adba1ffea6b1fc45ded9908 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 23 Aug 2024 08:13:26 +0100 Subject: [PATCH 052/238] [nrf fromtree] bootutil: loader: Remove encrypted/compressed images without support Checks if images have compressed or encrypted image flags and, if so, and those options are not enabled in that MCUboot build, will class the images as invalid and delete them (these images cannot be used without support anyway) Signed-off-by: Jamie McCrae (cherry picked from commit 206c7e749610b6a8855fb1598b9fe27d1eba08bf) --- boot/bootutil/src/loader.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index f1f2777b3..5566f005e 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -877,7 +877,9 @@ split_image_check(struct image_header *app_hdr, * Check that this is a valid header. Valid means that the magic is * correct, and that the sizes/offsets are "sane". Sane means that * there is no overflow on the arithmetic, and that the result fits - * within the flash area we are in. + * within the flash area we are in. Also check the flags in the image + * and class the image as invalid if flags for encryption/compression + * are present but these features are not enabled. */ static bool boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fap, @@ -899,6 +901,18 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa return false; } +#if !defined(MCUBOOT_ENC_IMAGES) + if (IS_ENCRYPTED(hdr)) { + return false; + } +#endif + +#if !defined(MCUBOOT_DECOMPRESS_IMAGES) + if (IS_COMPRESSED(hdr)) { + return false; + } +#endif + return true; } From cd557e1c4e3c11977aa34de0171a128275598cd8 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 23 Aug 2024 08:25:24 +0100 Subject: [PATCH 053/238] [nrf fromtree] bootutil: loader: Remove images with conflicting flags Marks images as invalid if they have conflicting flags, e.g. more than one type of LZMA compression or more than one type of encryption Signed-off-by: Jamie McCrae (cherry picked from commit 4d85e29f3d5ac67c1af9b2c8bac812ecc8249a3e) --- boot/bootutil/src/loader.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 5566f005e..fb0551a74 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -905,12 +905,24 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa if (IS_ENCRYPTED(hdr)) { return false; } +#else + if ((hdr->ih_flags & IMAGE_F_ENCRYPTED_AES128) && + (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES256)) + { + return false; + } #endif #if !defined(MCUBOOT_DECOMPRESS_IMAGES) if (IS_COMPRESSED(hdr)) { return false; } +#else + if ((hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1) && + (hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) + { + return false; + } #endif return true; From 7d67371134426c56d2312fd979c9c13a2ade8e78 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 23 Aug 2024 08:16:47 +0100 Subject: [PATCH 054/238] [nrf fromtree] bootutil: loader: Add protected TLV size to image size check The protected TLV section was not included in the size check of if an image could fit into a slot, which means that it was possible for file to be deemed as OK for storing but then failing due to insufficient flash space during the update Signed-off-by: Jamie McCrae (cherry picked from commit feb9265f91b7eec386afa7c5b906d92d3420d97f) --- boot/bootutil/src/loader.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index fb0551a74..22485861e 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -897,6 +897,16 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa return false; } +#ifdef MCUBOOT_DECOMPRESS_IMAGES + if (!MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), hdr)) { +#else + if (1) { +#endif + if (!boot_u32_safe_add(&size, size, hdr->ih_protect_tlv_size)) { + return false; + } + } + if (size >= flash_area_get_size(fap)) { return false; } From 21bac2b598e2bf8e91110f69127d55ae04c5202a Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 23 Aug 2024 08:51:11 +0100 Subject: [PATCH 055/238] [nrf fromtree] booutil: swap_scratch: Do not check sectors with compression When compression is used, it allows for the secondary slot to be smaller than the primary slot, therefore do not ensure that the number of sectors in each slot are the same Signed-off-by: Jamie McCrae (cherry picked from commit 2931f9d71f76cc127149152d5d386f4be0a18b1a) --- boot/bootutil/src/swap_scratch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index a32eb8d87..19be30c64 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -259,12 +259,14 @@ boot_slots_compatible(struct boot_loader_state *state) #endif } +#ifndef MCUBOOT_DECOMPRESS_IMAGES if ((i != num_sectors_primary) || (j != num_sectors_secondary) || (primary_slot_sz != secondary_slot_sz)) { BOOT_LOG_WRN("Cannot upgrade: slots are not compatible"); return 0; } +#endif return 1; #endif /* PM_S1_ADDRESS */ From 5eaeac3e5ea0ba3c211f122013911c820ebc188f Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 23 Aug 2024 08:28:40 +0100 Subject: [PATCH 056/238] [nrf fromtree] docs: release-notes: Add note on changes Adds release notes based on these changes Signed-off-by: Jamie McCrae (cherry picked from commit ebf60e03df6ed6b18b9da5a0a7f1982e2cff98ba) --- docs/release-notes.d/zephyr-compression.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docs/release-notes.d/zephyr-compression.md diff --git a/docs/release-notes.d/zephyr-compression.md b/docs/release-notes.d/zephyr-compression.md new file mode 100644 index 000000000..ba9ec2a7a --- /dev/null +++ b/docs/release-notes.d/zephyr-compression.md @@ -0,0 +1,7 @@ +- Added protected TLV size to image size check in bootutil +- Added Kconfig for decompression support in Zephyr +- Added compressed image flags and TLV to bootutil +- Added support for removing images with conflicting flags in + bootutil +- Added support for removing encrypted/compressed images when + MCUboot is compiled without support for them From 92121b1e20347ebd057e55a3e86e5774f6e32d04 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 22 Aug 2024 14:17:46 +0100 Subject: [PATCH 057/238] [nrf noup] zephyr: Add support for compressed image updates Adds support for LZMA-compressed firmware updates Signed-off-by: Jamie McCrae --- boot/bootutil/src/image_validate.c | 224 ++++ boot/bootutil/src/loader.c | 102 +- boot/zephyr/CMakeLists.txt | 6 + boot/zephyr/Kconfig | 5 + boot/zephyr/decompression.c | 1105 +++++++++++++++++ .../include/compression/decompression.h | 104 ++ 6 files changed, 1525 insertions(+), 21 deletions(-) create mode 100644 boot/zephyr/decompression.c create mode 100644 boot/zephyr/include/compression/decompression.h diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index a697676b6..81782edf2 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -40,6 +40,15 @@ #include "mcuboot_config/mcuboot_config.h" +#if defined(MCUBOOT_DECOMPRESS_IMAGES) +#include +#include +#endif + +#include "bootutil/bootutil_log.h" + +BOOT_LOG_MODULE_DECLARE(mcuboot); + #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" #endif @@ -412,6 +421,66 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, FIH_DECLARE(security_counter_valid, FIH_FAILURE); #endif +#ifdef MCUBOOT_DECOMPRESS_IMAGES + /* If the image is compressed, the integrity of the image must also be validated */ + if (MUST_DECOMPRESS(fap, image_index, hdr)) { + bool found_decompressed_size = false; + bool found_decompressed_sha = false; + bool found_decompressed_signature = false; + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, true); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(fap)) { + rc = -1; + goto out; + } + + while (true) { + uint16_t expected_size = 0; + bool *found_flag = NULL; + + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + break; + } + + switch (type) { + case IMAGE_TLV_DECOMP_SIZE: + expected_size = sizeof(size_t); + found_flag = &found_decompressed_size; + break; + case IMAGE_TLV_DECOMP_SHA: + expected_size = IMAGE_HASH_SIZE; + found_flag = &found_decompressed_sha; + break; + case IMAGE_TLV_DECOMP_SIGNATURE: + expected_size = SIG_BUF_SIZE; + found_flag = &found_decompressed_signature; + break; + default: + continue; + }; + + if (len != expected_size) { + rc = -1; + goto out; + } + + *found_flag = true; + } + + rc = (!found_decompressed_size || !found_decompressed_sha || !found_decompressed_signature); + if (rc) { + goto out; + } + } +#endif + rc = bootutil_img_hash(enc_state, image_index, hdr, fap, tmp_buf, tmp_buf_sz, hash, seed, seed_len); if (rc) { @@ -583,6 +652,161 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } #endif +#ifdef MCUBOOT_DECOMPRESS_IMAGES + /* Only after all previous verifications have passed, perform a dry-run of the decompression + * and ensure the image is valid + */ + if (!rc && MUST_DECOMPRESS(fap, image_index, hdr)) { + image_hash_valid = 0; + FIH_SET(valid_signature, FIH_FAILURE); + + rc = bootutil_img_hash_decompress(enc_state, image_index, hdr, fap, tmp_buf, tmp_buf_sz, + hash, seed, seed_len); + if (rc) { + goto out; + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SHA, true); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(fap)) { + rc = -1; + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + break; + } + + if (type == IMAGE_TLV_DECOMP_SHA) { + /* Verify the image hash. This must always be present. */ + if (len != sizeof(hash)) { + rc = -1; + goto out; + } + rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, sizeof(hash)); + if (rc) { + goto out; + } + + FIH_CALL(boot_fih_memequal, fih_rc, hash, buf, sizeof(hash)); + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + + image_hash_valid = 1; + } + } + + rc = !image_hash_valid; + if (rc) { + goto out; + } + +#ifdef EXPECTED_SIG_TLV +#ifdef EXPECTED_KEY_TLV + rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_KEY_TLV, false); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(fap)) { + rc = -1; + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + break; + } + + if (type == EXPECTED_KEY_TLV) { + /* + * Determine which key we should be checking. + */ + if (len > KEY_BUF_SIZE) { + rc = -1; + goto out; + } +#ifndef MCUBOOT_HW_KEY + rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, len); + if (rc) { + goto out; + } + key_id = bootutil_find_key(buf, len); +#else + rc = LOAD_IMAGE_DATA(hdr, fap, off, key_buf, len); + if (rc) { + goto out; + } + key_id = bootutil_find_key(image_index, key_buf, len); +#endif /* !MCUBOOT_HW_KEY */ + /* + * The key may not be found, which is acceptable. There + * can be multiple signatures, each preceded by a key. + */ + } + } +#endif /* EXPECTED_KEY_TLV */ + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIGNATURE, true); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(fap)) { + rc = -1; + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIGNATURE) { + /* Ignore this signature if it is out of bounds. */ + if (key_id < 0 || key_id >= bootutil_key_cnt) { + key_id = -1; + continue; + } + + if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) { + rc = -1; + goto out; + } + rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, len); + if (rc) { + goto out; + } + + FIH_CALL(bootutil_verify_sig, valid_signature, hash, sizeof(hash), + buf, len, key_id); + key_id = -1; + } + } +#endif /* EXPECTED_SIG_TLV */ + } +#endif + +#ifdef EXPECTED_SIG_TLV + FIH_SET(fih_rc, valid_signature); +#endif + out: if (rc) { FIH_SET(fih_rc, FIH_FAILURE); diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 22485861e..d35b6910c 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,6 +49,11 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" +#if defined(MCUBOOT_DECOMPRESS_IMAGES) +#include +#include +#endif + #ifdef __ZEPHYR__ #include #endif @@ -571,35 +576,76 @@ boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size) goto done; } - off = BOOT_TLV_OFF(boot_img_hdr(state, slot)); +#ifdef MCUBOOT_DECOMPRESS_IMAGES + if (MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), boot_img_hdr(state, slot))) { + uint32_t tmp_size = 0; - if (flash_area_read(fap, off, &info, sizeof(info))) { - rc = BOOT_EFLASH; - goto done; - } + rc = bootutil_get_img_decomp_size(boot_img_hdr(state, slot), fap, &tmp_size); + + if (rc) { + rc = BOOT_EBADIMAGE; + goto done; + } + + off = boot_img_hdr(state, slot)->ih_hdr_size + tmp_size; - protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size; - if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { - if (protect_tlv_size != info.it_tlv_tot) { + rc = boot_size_protected_tlvs(boot_img_hdr(state, slot), fap, &tmp_size); + + if (rc) { rc = BOOT_EBADIMAGE; goto done; } - if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) { + off += tmp_size; + + if (flash_area_read(fap, (BOOT_TLV_OFF(boot_img_hdr(state, slot)) + + boot_img_hdr(state, slot)->ih_protect_tlv_size), &info, + sizeof(info))) { rc = BOOT_EFLASH; goto done; } - } else if (protect_tlv_size != 0) { - rc = BOOT_EBADIMAGE; - goto done; - } - if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { - rc = BOOT_EBADIMAGE; - goto done; + if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { + rc = BOOT_EBADIMAGE; + goto done; + } + + *size = off + info.it_tlv_tot; + } else { +#else + if (1) { +#endif + off = BOOT_TLV_OFF(boot_img_hdr(state, slot)); + + if (flash_area_read(fap, off, &info, sizeof(info))) { + rc = BOOT_EFLASH; + goto done; + } + + protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size; + if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { + if (protect_tlv_size != info.it_tlv_tot) { + rc = BOOT_EBADIMAGE; + goto done; + } + + if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) { + rc = BOOT_EFLASH; + goto done; + } + } else if (protect_tlv_size != 0) { + rc = BOOT_EBADIMAGE; + goto done; + } + + if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { + rc = BOOT_EBADIMAGE; + goto done; + } + + *size = off + protect_tlv_size + info.it_tlv_tot; } - *size = off + protect_tlv_size + info.it_tlv_tot; rc = 0; done: @@ -928,10 +974,10 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa return false; } #else - if ((hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1) && - (hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) - { - return false; + if (MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), hdr)) { + if (!boot_is_compressed_header_valid(hdr, fap, state)) { + return false; + } } #endif @@ -1111,6 +1157,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * attempts to validate and boot it. */ } + #if !defined(__BOOTSIM__) BOOT_LOG_ERR("Image in the %s slot is not valid!", (slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary"); @@ -1534,6 +1581,9 @@ boot_copy_region(struct boot_loader_state *state, uint32_t blk_sz; uint8_t image_index; #endif +#ifdef MCUBOOT_DECOMPRESS_IMAGES + struct image_header *hdr; +#endif TARGET_STATIC uint8_t buf[BUF_SZ] __attribute__((aligned(4))); @@ -1541,6 +1591,16 @@ boot_copy_region(struct boot_loader_state *state, (void)state; #endif +#ifdef MCUBOOT_DECOMPRESS_IMAGES + hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + + if (MUST_DECOMPRESS(fap_src, BOOT_CURR_IMG(state), hdr)) { + /* Use alternative function for compressed images */ + return boot_copy_region_decompress(state, fap_src, fap_dst, off_src, off_dst, sz, buf, + BUF_SZ); + } +#endif + bytes_copied = 0; while (bytes_copied < sz) { if (sz - bytes_copied > sizeof buf) { diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 387623dae..c26633d11 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -251,6 +251,12 @@ if(CONFIG_BOOT_ENCRYPT_EC256) ) endif() +if(CONFIG_BOOT_DECOMPRESSION) + zephyr_library_sources( + decompression.c + ) +endif() + if(CONFIG_MCUBOOT_SERIAL) zephyr_sources(${BOOT_DIR}/zephyr/serial_adapter.c) zephyr_sources(${BOOT_DIR}/boot_serial/src/boot_serial.c) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 2dbfc3135..28f40bf52 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -723,6 +723,10 @@ config BOOT_BANNER_STRING config BOOT_DECOMPRESSION_SUPPORT bool + depends on NRF_COMPRESS && NRF_COMPRESS_DECOMPRESSION && (NRF_COMPRESS_LZMA_VERSION_LZMA1 || NRF_COMPRESS_LZMA_VERSION_LZMA2) + depends on !SINGLE_APPLICATION_SLOT && !BOOT_ENCRYPT_IMAGE && BOOT_UPGRADE_ONLY + depends on UPDATEABLE_IMAGE_NUMBER = 1 + default y help Hidden symbol which should be selected if a system provided decompression support. @@ -730,6 +734,7 @@ if BOOT_DECOMPRESSION_SUPPORT menuconfig BOOT_DECOMPRESSION bool "Decompression" + select NRF_COMPRESS_CLEANUP help If enabled, will include support for compressed images being loaded to the secondary slot which then get decompressed into the primary slot. This mode allows the secondary slot to diff --git a/boot/zephyr/decompression.c b/boot/zephyr/decompression.c new file mode 100644 index 000000000..5d491adcf --- /dev/null +++ b/boot/zephyr/decompression.c @@ -0,0 +1,1105 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include "compression/decompression.h" +#include "bootutil/crypto/sha.h" +#include "bootutil/bootutil_log.h" + +#if !defined(__BOOTSIM__) +#define TARGET_STATIC static +#else +#define TARGET_STATIC +#endif + +#if defined(MCUBOOT_SIGN_RSA) +#if MCUBOOT_SIGN_RSA_LEN == 2048 +#define EXPECTED_SIG_TLV IMAGE_TLV_RSA2048_PSS +#elif MCUBOOT_SIGN_RSA_LEN == 3072 +#define EXPECTED_SIG_TLV IMAGE_TLV_RSA3072_PSS +#endif +#elif defined(MCUBOOT_SIGN_EC256) || \ + defined(MCUBOOT_SIGN_EC384) || \ + defined(MCUBOOT_SIGN_EC) +#define EXPECTED_SIG_TLV IMAGE_TLV_ECDSA_SIG +#elif defined(MCUBOOT_SIGN_ED25519) +#define EXPECTED_SIG_TLV IMAGE_TLV_ED25519 +#endif + +/* Number of times that consumed data by decompression system can be 0 in a row before aborting */ +#define OFFSET_ZERO_CHECK_TIMES 3 + +BOOT_LOG_MODULE_DECLARE(mcuboot); + +static int boot_sha_protected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, uint32_t protected_size, + uint8_t *buf, size_t buf_size, bootutil_sha_context *sha_ctx); + +bool boot_is_compressed_header_valid(const struct image_header *hdr, const struct flash_area *fap, + struct boot_loader_state *state) +{ + /* Image is compressed in secondary slot, need to check if fits into the primary slot */ + bool opened_flash_area = false; + int primary_fa_id; + int rc; + int size_check; + int size; + uint32_t protected_tlvs_size; + uint32_t decompressed_size; + + if (BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT) == NULL) { + opened_flash_area = true; + } + + primary_fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT); + rc = flash_area_open(primary_fa_id, &BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); + assert(rc == 0); + + size_check = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); + + if (opened_flash_area) { + (void)flash_area_close(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); + } + + rc = bootutil_get_img_decomp_size(hdr, fap, &decompressed_size); + + if (rc) { + return false; + } + + if (!boot_u32_safe_add(&size, decompressed_size, hdr->ih_hdr_size)) { + return false; + } + + rc = boot_size_protected_tlvs(hdr, fap, &protected_tlvs_size); + + if (rc) { + return false; + } + + if (!boot_u32_safe_add(&size, size, protected_tlvs_size)) { + return false; + } + + if (size >= size_check) { + BOOT_LOG_ERR("Compressed image too large, decompressed image size: 0x%x, slot size: 0x%x", + size, size_check); + + return false; + } + + return true; +} + +int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index, + struct image_header *hdr, const struct flash_area *fap, + uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result, + uint8_t *seed, int seed_len) +{ + int rc; + uint32_t read_pos = 0; + uint32_t write_pos = 0; + uint32_t protected_tlv_size = 0; + uint32_t decompressed_image_size; + struct nrf_compress_implementation *compression = NULL; + TARGET_STATIC struct image_header modified_hdr; + bootutil_sha_context sha_ctx; + uint8_t flash_erased_value; + + bootutil_sha_init(&sha_ctx); + + /* Setup decompression system */ +#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) { +#elif CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) { +#endif + /* Compressed image does not use the correct compression type which is supported by this + * build + */ + BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); + rc = BOOT_EBADIMAGE; + + goto finish_without_clean; + } + + compression = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + if (compression == NULL || compression->init == NULL || compression->deinit == NULL || + compression->decompress_bytes_needed == NULL || compression->decompress == NULL) { + /* Compression library missing or missing required function pointer */ + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + + goto finish_without_clean; + } + + rc = compression->init(NULL); + + if (rc) { + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + + goto finish_without_clean; + } + + /* We need a modified header which has the updated sizes, start with the original header */ + memcpy(&modified_hdr, hdr, sizeof(modified_hdr)); + + /* Extract the decompressed image size from the protected TLV, set it and remove the + * compressed image flags + */ + rc = bootutil_get_img_decomp_size(hdr, fap, &decompressed_image_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + modified_hdr.ih_flags &= ~COMPRESSIONFLAGS; + modified_hdr.ih_img_size = decompressed_image_size; + + /* Calculate the protected TLV size, these will not include the decompressed + * sha/size/signature entries + */ + rc = boot_size_protected_tlvs(hdr, fap, &protected_tlv_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + modified_hdr.ih_protect_tlv_size = protected_tlv_size; + bootutil_sha_update(&sha_ctx, &modified_hdr, sizeof(modified_hdr)); + read_pos = sizeof(modified_hdr); + flash_erased_value = flash_area_erased_val(fap); + memset(tmp_buf, flash_erased_value, tmp_buf_sz); + + while (read_pos < modified_hdr.ih_hdr_size) { + uint32_t copy_size = tmp_buf_sz; + + if ((read_pos + copy_size) > modified_hdr.ih_hdr_size) { + copy_size = modified_hdr.ih_hdr_size - read_pos; + } + + bootutil_sha_update(&sha_ctx, tmp_buf, copy_size); + read_pos += copy_size; + } + + /* Read in compressed data, decompress and add to hash calculation */ + read_pos = 0; + + while (read_pos < hdr->ih_img_size) { + uint32_t copy_size = hdr->ih_img_size - read_pos; + uint32_t tmp_off = 0; + uint8_t offset_zero_check = 0; + + if (copy_size > tmp_buf_sz) { + copy_size = tmp_buf_sz; + } + + rc = flash_area_read(fap, (hdr->ih_hdr_size + read_pos), tmp_buf, copy_size); + + if (rc != 0) { + BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (hdr->ih_hdr_size + read_pos), copy_size, fap->fa_id, rc); + rc = BOOT_EFLASH; + + goto finish; + } + + /* Decompress data in chunks, writing it back with a larger write offset of the primary + * slot than read size of the secondary slot + */ + while (tmp_off < copy_size) { + uint32_t offset = 0; + uint8_t *output = NULL; + uint32_t output_size = 0; + uint32_t chunk_size; + bool last_packet = false; + + chunk_size = compression->decompress_bytes_needed(NULL); + + if (chunk_size > (copy_size - tmp_off)) { + chunk_size = (copy_size - tmp_off); + } + + if ((read_pos + tmp_off + chunk_size) >= hdr->ih_img_size) { + last_packet = true; + } + + rc = compression->decompress(NULL, &tmp_buf[tmp_off], chunk_size, last_packet, &offset, + &output, &output_size); + + if (rc) { + BOOT_LOG_ERR("Decompression error: %d", rc); + rc = BOOT_EBADSTATUS; + + goto finish; + } + + write_pos += output_size; + + if (write_pos > decompressed_image_size) { + BOOT_LOG_ERR("Decompressed image larger than claimed TLV size, at least: %d", + write_pos); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + /* Additional dry-run validity checks */ + if (last_packet == true && write_pos == 0) { + /* Last packet and we still have no output, this is a faulty update */ + BOOT_LOG_ERR("All compressed data consumed without any output, image not valid"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + if (offset == 0) { + /* If the decompression system continually consumes 0 bytes, then there is a + * problem with this update image, abort and mark image as bad + */ + if (offset_zero_check >= OFFSET_ZERO_CHECK_TIMES) { + BOOT_LOG_ERR("Decompression system returning no output data, image not valid"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + ++offset_zero_check; + + break; + } else { + offset_zero_check = 0; + } + + if (output_size > 0) { + bootutil_sha_update(&sha_ctx, output, output_size); + } + + tmp_off += offset; + } + + read_pos += copy_size; + } + + /* If there are any protected TLVs present, add them after the main decompressed image */ + if (modified_hdr.ih_protect_tlv_size > 0) { + rc = boot_sha_protected_tlvs(hdr, fap, modified_hdr.ih_protect_tlv_size, tmp_buf, + tmp_buf_sz, &sha_ctx); + } + + bootutil_sha_finish(&sha_ctx, hash_result); + +finish: + /* Clean up decompression system */ + (void)compression->deinit(NULL); + +finish_without_clean: + bootutil_sha_drop(&sha_ctx); + + return rc; +} + +static int boot_copy_protected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_dst, + uint32_t protected_size, uint8_t *buf, size_t buf_size, + uint16_t *buf_pos, uint32_t *written) +{ + int rc; + uint32_t off; + uint32_t write_pos = 0; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + struct image_tlv tlv_header; + struct image_tlv_info tlv_info_header = { + .it_magic = IMAGE_TLV_PROT_INFO_MAGIC, + .it_tlv_tot = protected_size, + }; + uint16_t info_size_left = sizeof(tlv_info_header); + + while (info_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + + if (info_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + uint8_t *tlv_info_header_address = (uint8_t *)&tlv_info_header; + + if (single_copy_size > info_size_left) { + single_copy_size = info_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_info_header_address[sizeof(tlv_info_header) - + info_size_left], single_copy_size); + *buf_pos += single_copy_size; + info_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, true); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || + type == IMAGE_TLV_DECOMP_SIGNATURE) { + /* Skip these TLVs as they are not needed */ + continue; + } else { + uint16_t header_size_left = sizeof(tlv_header); + uint16_t data_size_left = len; + + tlv_header.it_type = type; + tlv_header.it_len = len; + + while (header_size_left > 0 || data_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + uint8_t *tlv_header_address = (uint8_t *)&tlv_header; + + if (header_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + + if (single_copy_size > header_size_left) { + single_copy_size = header_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_header_address[sizeof(tlv_header) - + header_size_left], + single_copy_size); + *buf_pos += single_copy_size; + copy_size -= single_copy_size; + header_size_left -= single_copy_size; + } + + if (data_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + + if (single_copy_size > data_size_left) { + single_copy_size = data_size_left; + } + + rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + (len - data_size_left)), + &buf[*buf_pos], single_copy_size); + + if (rc) { + BOOT_LOG_ERR( + "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); + + goto out; + } + + *buf_pos += single_copy_size; + data_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR( + "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + } + } + + *written = write_pos; + +out: + return rc; +} + +static int boot_sha_protected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, uint32_t protected_size, + uint8_t *buf, size_t buf_size, bootutil_sha_context *sha_ctx) +{ + int rc; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + struct image_tlv tlv_header; + struct image_tlv_info tlv_info_header = { + .it_magic = IMAGE_TLV_PROT_INFO_MAGIC, + .it_tlv_tot = protected_size, + }; + + bootutil_sha_update(sha_ctx, &tlv_info_header, sizeof(tlv_info_header)); + + rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, true); + if (rc) { + goto out; + } + + while (true) { + uint32_t read_off = 0; + + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || + type == IMAGE_TLV_DECOMP_SIGNATURE) { + /* Skip these TLVs as they are not needed */ + continue; + } + + tlv_header.it_type = type; + tlv_header.it_len = len; + + bootutil_sha_update(sha_ctx, &tlv_header, sizeof(tlv_header)); + + while (read_off < len) { + uint32_t copy_size = buf_size; + + if (copy_size > (len - read_off)) { + copy_size = len - read_off; + } + + rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + read_off), buf, copy_size); + + if (rc) { + BOOT_LOG_ERR( + "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off + read_off), copy_size, fap_src->fa_id, rc); + + goto out; + } + + bootutil_sha_update(sha_ctx, buf, copy_size); + read_off += copy_size; + } + } + +out: + return rc; +} + +int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *sz) +{ + int rc = 0; + uint32_t tlv_size; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + + *sz = 0; + tlv_size = hdr->ih_protect_tlv_size; + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, true); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || + type == IMAGE_TLV_DECOMP_SIGNATURE) { + /* Exclude these TLVs as they will be copied to the unprotected area */ + tlv_size -= len + sizeof(struct image_tlv); + } + } + + if (!rc) { + if (tlv_size == sizeof(struct image_tlv_info)) { + /* If there are no entries then omit protected TLV section entirely */ + tlv_size = 0; + } + + *sz = tlv_size; + } + +out: + return rc; +} + +int boot_size_unprotected_tlvs(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *sz) +{ + int rc = 0; + uint32_t tlv_size; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + + *sz = 0; + tlv_size = sizeof(struct image_tlv_info); + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } else if (bootutil_tlv_iter_is_prot(&it, off)) { + continue; + } + + tlv_size += len + sizeof(struct image_tlv); + } + + if (!rc) { + if (tlv_size == sizeof(struct image_tlv_info)) { + /* If there are no entries in the unprotected TLV section then there is something wrong + * with this image + */ + BOOT_LOG_ERR("No unprotected TLVs in post-decompressed image output, image is invalid"); + rc = BOOT_EBADIMAGE; + + goto out; + } + + *sz = tlv_size; + } + +out: + return rc; +} + +static int boot_copy_unprotected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_dst, + uint32_t unprotected_size, uint8_t *buf, size_t buf_size, + uint16_t *buf_pos, uint32_t *written) +{ + int rc; + uint32_t write_pos = 0; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + struct image_tlv_iter it_protected; + struct image_tlv tlv_header; + struct image_tlv_info tlv_info_header = { + .it_magic = IMAGE_TLV_INFO_MAGIC, + .it_tlv_tot = unprotected_size, + }; + uint16_t info_size_left = sizeof(tlv_info_header); + + while (info_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + + if (info_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + uint8_t *tlv_info_header_address = (uint8_t *)&tlv_info_header; + + if (single_copy_size > info_size_left) { + single_copy_size = info_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_info_header_address[sizeof(tlv_info_header) - + info_size_left], single_copy_size); + *buf_pos += single_copy_size; + info_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, false); + if (rc) { + goto out; + } + + while (true) { + uint16_t header_size_left = sizeof(tlv_header); + uint16_t data_size_left; + + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } else if (bootutil_tlv_iter_is_prot(&it, off)) { + /* Skip protected TLVs */ + continue; + } + + /* Change the values of these fields from having the data in the compressed image + * unprotected TLV (which is valid only for the compressed image data) to having the + * fields in the protected TLV section (which is valid for the decompressed image data). + * The compressed data is no longer needed + */ + if (type == EXPECTED_HASH_TLV || type == EXPECTED_SIG_TLV) { + rc = bootutil_tlv_iter_begin(&it_protected, hdr, fap_src, (type == EXPECTED_HASH_TLV ? + IMAGE_TLV_DECOMP_SHA : + IMAGE_TLV_DECOMP_SIGNATURE), + true); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it_protected, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + } + + if (type == IMAGE_TLV_DECOMP_SHA) { + type = EXPECTED_HASH_TLV; + } else { + type = EXPECTED_SIG_TLV; + } + } + + data_size_left = len; + tlv_header.it_type = type; + tlv_header.it_len = len; + + while (header_size_left > 0 || data_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + + if (header_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + uint8_t *tlv_header_address = (uint8_t *)&tlv_header; + + if (single_copy_size > header_size_left) { + single_copy_size = header_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_header_address[sizeof(tlv_header) - header_size_left], + single_copy_size); + *buf_pos += single_copy_size; + copy_size -= single_copy_size; + header_size_left -= single_copy_size; + } + + if (data_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + + if (single_copy_size > data_size_left) { + single_copy_size = data_size_left; + } + + rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + len - data_size_left), + &buf[*buf_pos], single_copy_size); + + if (rc) { + BOOT_LOG_ERR( + "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); + + goto out; + } + + *buf_pos += single_copy_size; + data_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR( + "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + } + + *written = write_pos; + +out: + return rc; +} + +int boot_copy_region_decompress(struct boot_loader_state *state, const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_src, + uint32_t off_dst, uint32_t sz, uint8_t *buf, size_t buf_size) +{ + int rc; + uint32_t pos = 0; + uint16_t decomp_buf_size = 0; + uint16_t write_alignment; + uint32_t write_pos = 0; + uint32_t protected_tlv_size = 0; + uint32_t unprotected_tlv_size = 0; + uint32_t tlv_write_size = 0; + uint32_t decompressed_image_size; + struct nrf_compress_implementation *compression = NULL; + struct image_header *hdr; + TARGET_STATIC uint8_t decomp_buf[CONFIG_BOOT_DECOMPRESSION_BUFFER_SIZE] __attribute__((aligned(4))); + TARGET_STATIC struct image_header modified_hdr; + + hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + + /* Setup decompression system */ +#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) { +#elif CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) { +#endif + /* Compressed image does not use the correct compression type which is supported by this + * build + */ + BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + compression = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + if (compression == NULL || compression->init == NULL || compression->deinit == NULL || + compression->decompress_bytes_needed == NULL || compression->decompress == NULL) { + /* Compression library missing or missing required function pointer */ + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + + goto finish; + } + + rc = compression->init(NULL); + + if (rc) { + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + + goto finish; + } + + write_alignment = flash_area_align(fap_dst); + + memcpy(&modified_hdr, hdr, sizeof(modified_hdr)); + + rc = bootutil_get_img_decomp_size(hdr, fap_src, &decompressed_image_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + modified_hdr.ih_flags &= ~COMPRESSIONFLAGS; + modified_hdr.ih_img_size = decompressed_image_size; + + /* Calculate protected TLV size for target image once items are removed */ + rc = boot_size_protected_tlvs(hdr, fap_src, &protected_tlv_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + modified_hdr.ih_protect_tlv_size = protected_tlv_size; + + rc = boot_size_unprotected_tlvs(hdr, fap_src, &unprotected_tlv_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine unprotected TLV size of compressed image"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + /* Write out the image header first, this should be a multiple of the write size */ + rc = flash_area_write(fap_dst, off_dst, &modified_hdr, sizeof(modified_hdr)); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + off_dst, sizeof(modified_hdr), fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto finish; + } + + /* Read in, decompress and write out data */ + while (pos < hdr->ih_img_size) { + uint32_t copy_size = hdr->ih_img_size - pos; + uint32_t tmp_off = 0; + + if (copy_size > buf_size) { + copy_size = buf_size; + } + + rc = flash_area_read(fap_src, off_src + hdr->ih_hdr_size + pos, buf, copy_size); + + if (rc != 0) { + BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_src + hdr->ih_hdr_size + pos), copy_size, fap_src->fa_id, rc); + rc = BOOT_EFLASH; + + goto finish; + } + + /* Decompress data in chunks, writing it back with a larger write offset of the primary + * slot than read size of the secondary slot + */ + while (tmp_off < copy_size) { + uint32_t offset = 0; + uint32_t output_size = 0; + uint32_t chunk_size; + uint32_t compression_buffer_pos = 0; + uint8_t *output = NULL; + bool last_packet = false; + + chunk_size = compression->decompress_bytes_needed(NULL); + + if (chunk_size > (copy_size - tmp_off)) { + chunk_size = (copy_size - tmp_off); + } + + if ((pos + tmp_off + chunk_size) >= hdr->ih_img_size) { + last_packet = true; + } + + rc = compression->decompress(NULL, &buf[tmp_off], chunk_size, last_packet, &offset, + &output, &output_size); + + if (rc) { + BOOT_LOG_ERR("Decompression error: %d", rc); + rc = BOOT_EBADSTATUS; + + goto finish; + } + + /* Copy data to secondary buffer for writing out */ + while (output_size > 0) { + uint32_t data_size = (sizeof(decomp_buf) - decomp_buf_size); + + if (data_size > output_size) { + data_size = output_size; + } + + memcpy(&decomp_buf[decomp_buf_size], &output[compression_buffer_pos], data_size); + compression_buffer_pos += data_size; + + decomp_buf_size += data_size; + output_size -= data_size; + + /* Write data out from secondary buffer when it is full */ + if (decomp_buf_size == sizeof(decomp_buf)) { + rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), + decomp_buf, sizeof(decomp_buf)); + + if (rc != 0) { + BOOT_LOG_ERR( + "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + hdr->ih_hdr_size + write_pos), sizeof(decomp_buf), + fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto finish; + } + + write_pos += sizeof(decomp_buf); + decomp_buf_size = 0; + } + } + + tmp_off += offset; + } + + pos += copy_size; + } + + /* Clean up decompression system */ + (void)compression->deinit(NULL); + + if (protected_tlv_size > 0) { + rc = boot_copy_protected_tlvs(hdr, fap_src, fap_dst, (off_dst + hdr->ih_hdr_size + + write_pos), protected_tlv_size, + decomp_buf, sizeof(decomp_buf_size), &decomp_buf_size, + &tlv_write_size); + + if (rc) { + BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); + + goto finish; + } + + write_pos += tlv_write_size; + } + + tlv_write_size = 0; + rc = boot_copy_unprotected_tlvs(hdr, fap_src, fap_dst, (off_dst + hdr->ih_hdr_size + + write_pos), unprotected_tlv_size, + decomp_buf, sizeof(decomp_buf_size), &decomp_buf_size, + &tlv_write_size); + + if (rc) { + BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); + + goto finish; + } + + write_pos += tlv_write_size; + + /* Check if we have unwritten data buffered up and, if so, write it out */ + if (decomp_buf_size > 0) { + uint32_t write_padding_size = decomp_buf_size % write_alignment; + + /* Check if additional write padding should be applied to meet the minimum write size */ + if (write_padding_size) { + uint8_t flash_erased_value; + + flash_erased_value = flash_area_erased_val(fap_dst); + memset(&decomp_buf[decomp_buf_size], flash_erased_value, write_padding_size); + decomp_buf_size += write_padding_size; + } + + rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), decomp_buf, + decomp_buf_size); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + hdr->ih_hdr_size + write_pos), sizeof(decomp_buf_size), + fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto finish; + } + + write_pos += decomp_buf_size; + decomp_buf_size = 0; + } + +finish: + memset(decomp_buf, 0, sizeof(decomp_buf)); + + return rc; +} + +int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *img_decomp_size) +{ + struct image_tlv_iter it; + uint32_t off; + uint16_t len; + int32_t rc; + + if (hdr == NULL || fap == NULL || img_decomp_size == NULL) { + return BOOT_EBADARGS; + } else if (hdr->ih_protect_tlv_size == 0) { + return BOOT_EBADIMAGE; + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIZE, true); + + if (rc) { + return rc; + } + + rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); + + if (rc != 0) { + return -1; + } + + if (len != sizeof(*img_decomp_size)) { + BOOT_LOG_ERR("Invalid decompressed image size TLV: %d", len); + + return BOOT_EBADIMAGE; + } + + rc = LOAD_IMAGE_DATA(hdr, fap, off, img_decomp_size, len); + + if (rc) { + BOOT_LOG_ERR("Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + off, len, fap->fa_id, rc); + + return BOOT_EFLASH; + } + + return 0; +} diff --git a/boot/zephyr/include/compression/decompression.h b/boot/zephyr/include/compression/decompression.h new file mode 100644 index 000000000..f8a676ac5 --- /dev/null +++ b/boot/zephyr/include/compression/decompression.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef H_DECOMPRESSION_ +#define H_DECOMPRESSION_ + +#include +#include +#include +#include "bootutil/bootutil.h" +#include "bootutil/bootutil_public.h" +#include "bootutil/image.h" +#include "../src/bootutil_priv.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Checks if a compressed image header is valid. + * + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param state Bootloader state object. + * + * @return true if valid; false if invalid. + */ +bool boot_is_compressed_header_valid(const struct image_header *hdr, const struct flash_area *fap, + struct boot_loader_state *state); + +/** + * Reads in compressed image data from a slot, decompresses it and writes it out to a destination + * slot, including corresponding image headers and TLVs. + * + * @param state Bootloader state object. + * @param fap_src Flash area of the source slot. + * @param fap_dst Flash area of the destination slot. + * @param off_src Offset of the source slot to read from (should be 0). + * @param off_dst Offset of the destination slot to write to (should be 0). + * @param sz Size of the source slot data. + * @param buf Temporary buffer for reading data from. + * @param buf_size Size of temporary buffer. + * + * @return 0 on success; nonzero on failure. + */ +int boot_copy_region_decompress(struct boot_loader_state *state, const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_src, + uint32_t off_dst, uint32_t sz, uint8_t *buf, size_t buf_size); + +/** + * Gets the total data size (excluding headers and TLVs) of a compressed image when it is + * decompressed. + * + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param img_decomp_size Pointer to variable that will be updated with the decompressed image + * size. + * + * @return 0 on success; nonzero on failure. + */ +int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *img_decomp_size); + +/** + * Calculate MCUboot-compatible image hash of compressed image slot. + * + * @param enc_state Not currently used, set to NULL. + * @param image_index Image number. + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param tmp_buf Temporary buffer for reading data from. + * @param tmp_buf_sz Size of temporary buffer. + * @param hash_result Pointer to a variable that will be updated with the image hash. + * @param seed Not currently used, set to NULL. + * @param seed_len Not currently used, set to 0. + * + * @return 0 on success; nonzero on failure. + */ +int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index, + struct image_header *hdr, const struct flash_area *fap, + uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result, + uint8_t *seed, int seed_len); + +/** + * Calculates the size that the compressed image protected TLV section will occupy once the image + * has been decompressed. + * + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param sz Pointer to variable that will be updated with the protected TLV size. + * + * @return 0 on success; nonzero on failure. + */ +int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_area *fap_src, + uint32_t *sz); + +#ifdef __cplusplus +} +#endif + +#endif /* H_DECOMPRESSION_ */ From c92b293e48c97b0e763e7d5c78de21c01f272036 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 25 Sep 2024 14:55:11 +0000 Subject: [PATCH 058/238] Revert "[nrf noup] crypto: ecdsa: Fix shared crypto MCUBoot EXT_ABI" This reverts commit 895c76beb540d91cd9ddb53198bbfde0089c36d4. Signed-off-by: Dominik Ermel --- boot/bootutil/include/bootutil/crypto/ecdsa.h | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index 450450dc3..eb3e33ee0 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -73,7 +73,7 @@ #if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) #include - #define NUM_ECC_BYTES (256 / 8) + #define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (4 * 8) #endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ #ifdef __cplusplus @@ -81,8 +81,7 @@ extern "C" { #endif #if (defined(MCUBOOT_USE_TINYCRYPT) || defined(MCUBOOT_USE_MBED_TLS) || \ - defined(MCUBOOT_USE_CC310) || defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO)) \ - && !defined(MCUBOOT_USE_PSA_CRYPTO) + defined(MCUBOOT_USE_CC310)) && !defined(MCUBOOT_USE_PSA_CRYPTO) /* * Declaring these like this adds NULL termination. */ @@ -623,45 +622,43 @@ static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, #endif /* MCUBOOT_USE_MBED_TLS */ #if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) -typedef uintptr_t bootutil_ecdsa_context; -static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) +typedef uintptr_t bootutil_ecdsa_p256_context; + +static inline void bootutil_ecdsa_p256_init(bootutil_ecdsa_p256_context *ctx) { (void)ctx; } -static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx) +static inline void bootutil_ecdsa_p256_drop(bootutil_ecdsa_p256_context *ctx) { (void)ctx; } -static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, - uint8_t *pk, size_t pk_len, - uint8_t *hash, size_t hash_len, - uint8_t *sig, size_t sig_len) +static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, + uint8_t *pk, size_t pk_len, + uint8_t *hash, + uint8_t *sig, size_t sig_len) { (void)ctx; (void)pk_len; - (void)hash_len; uint8_t dsig[2 * NUM_ECC_BYTES]; if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { return -1; } - /* Only support uncompressed keys. */ - if (pk[0] != 0x04) { - return -1; - } - pk++; + /* As described on the compact representation in IETF protocols, + * the first byte of the key defines if the ECC points are + * compressed (0x2 or 0x3) or uncompressed (0x4). + * We only support uncompressed keys. + */ + if (pk[0] != 0x04) + return -1; - return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, pk, dsig); -} + pk++; -static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, - uint8_t **cp,uint8_t *end) -{ - (void)ctx; - return bootutil_import_key(cp, end); + return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, + pk, dsig); } #endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ From 3f541bf4f3afdac243f684301a766235c2606214 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 25 Sep 2024 14:55:28 +0000 Subject: [PATCH 059/238] Revert "[nrf noup] crypto: ecdsa: Add required signature decoding" This reverts commit a42e9cc5fa46b614e60353d6a255984f72ab4d7e. Signed-off-by: Dominik Ermel --- boot/bootutil/include/bootutil/crypto/ecdsa.h | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index eb3e33ee0..5e79cd1bf 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -133,6 +133,8 @@ static int bootutil_import_key(uint8_t **cp, uint8_t *end) } #endif /* (MCUBOOT_USE_TINYCRYPT || MCUBOOT_USE_MBED_TLS || MCUBOOT_USE_CC310) && !MCUBOOT_USE_PSA_CRYPTO */ +#if defined(MCUBOOT_USE_TINYCRYPT) +#ifndef MCUBOOT_ECDSA_NEED_ASN1_SIG /* * cp points to ASN1 string containing an integer. * Verify the tag, and that the length is 32 bytes. Helper function. @@ -182,8 +184,8 @@ static int bootutil_decode_sig(uint8_t signature[NUM_ECC_BYTES * 2], uint8_t *cp } return 0; } +#endif /* not MCUBOOT_ECDSA_NEED_ASN1_SIG */ -#if defined(MCUBOOT_USE_TINYCRYPT) typedef uintptr_t bootutil_ecdsa_context; static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) { @@ -252,12 +254,8 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, { (void)ctx; (void)pk_len; + (void)sig_len; (void)hash_len; - uint8_t dsig[2 * NUM_ECC_BYTES]; - - if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { - return -1; - } /* Only support uncompressed keys. */ if (pk[0] != 0x04) { @@ -265,7 +263,7 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, } pk++; - return cc310_ecdsa_verify_secp256r1(hash, pk, dsig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); + return cc310_ecdsa_verify_secp256r1(hash, pk, sig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); } static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, @@ -641,11 +639,7 @@ static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, { (void)ctx; (void)pk_len; - uint8_t dsig[2 * NUM_ECC_BYTES]; - - if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { - return -1; - } + (void)sig_len; /* As described on the compact representation in IETF protocols, * the first byte of the key defines if the ECC points are @@ -658,7 +652,7 @@ static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, pk++; return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, - pk, dsig); + pk, sig); } #endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ From 2b1a6a4589b0a9d3d79698f895bb558327985b5e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 26 Sep 2024 10:57:11 +0000 Subject: [PATCH 060/238] Revert "[nrf noup] zephyr: disabled EXT_API_ATLEAST_OPTIONAL" This reverts commit cc42516352e797433e6e0413fc41e08d2b583739. Signed-off-by: Dominik Ermel --- boot/zephyr/external_crypto.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/external_crypto.conf b/boot/zephyr/external_crypto.conf index 8181ad51c..c362f000a 100644 --- a/boot/zephyr/external_crypto.conf +++ b/boot/zephyr/external_crypto.conf @@ -18,3 +18,4 @@ CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y CONFIG_SB_CRYPTO_CLIENT_SHA256=y CONFIG_BL_SHA256_EXT_API_REQUIRED=y CONFIG_BL_SECP256R1_EXT_API_REQUIRED=y +CONFIG_EXT_API_PROVIDE_EXT_API_ATLEAST_OPTIONAL=y From 48bf175e2a4f48d7b3dca8923b7ef2ae5b00b208 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 26 Sep 2024 10:57:23 +0000 Subject: [PATCH 061/238] Revert "[nrf noup] zephyr: Set at least provide EXT_API" This reverts commit ff5338297c4be31e757f99d8cf5730b05a5cbed6. Signed-off-by: Dominik Ermel --- boot/zephyr/external_crypto.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/external_crypto.conf b/boot/zephyr/external_crypto.conf index c362f000a..8181ad51c 100644 --- a/boot/zephyr/external_crypto.conf +++ b/boot/zephyr/external_crypto.conf @@ -18,4 +18,3 @@ CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y CONFIG_SB_CRYPTO_CLIENT_SHA256=y CONFIG_BL_SHA256_EXT_API_REQUIRED=y CONFIG_BL_SECP256R1_EXT_API_REQUIRED=y -CONFIG_EXT_API_PROVIDE_EXT_API_ATLEAST_OPTIONAL=y From 0cdbc8884b0bbfa38436d33a27429ef0a47b026e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 26 Sep 2024 10:57:50 +0000 Subject: [PATCH 062/238] Revert "[nrf noup] boot: Add shared crypto for ECDSA and SHA" This reverts commit 0faa8b2bb51bd58c9a1d3470f78f7b4136999652. Signed-off-by: Dominik Ermel --- boot/bootutil/include/bootutil/crypto/ecdsa.h | 43 ------------------- boot/bootutil/include/bootutil/crypto/sha.h | 32 -------------- boot/zephyr/CMakeLists.txt | 2 - boot/zephyr/external_crypto.conf | 20 --------- .../include/mcuboot_config/mcuboot_config.h | 5 ++- 5 files changed, 3 insertions(+), 99 deletions(-) delete mode 100644 boot/zephyr/external_crypto.conf diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index 5e79cd1bf..5a87f736b 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -34,7 +34,6 @@ #if (defined(MCUBOOT_USE_TINYCRYPT) + \ defined(MCUBOOT_USE_CC310) + \ - defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_PSA_OR_MBED_TLS)) != 1 #error "One crypto backend must be defined: either CC310/TINYCRYPT/MBED_TLS/PSA_CRYPTO" #endif @@ -71,11 +70,6 @@ #include "bootutil/sign_key.h" #include "common.h" -#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) - #include - #define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (4 * 8) -#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ - #ifdef __cplusplus extern "C" { #endif @@ -619,43 +613,6 @@ static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, #endif /* MCUBOOT_USE_MBED_TLS */ -#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) -typedef uintptr_t bootutil_ecdsa_p256_context; - -static inline void bootutil_ecdsa_p256_init(bootutil_ecdsa_p256_context *ctx) -{ - (void)ctx; -} - -static inline void bootutil_ecdsa_p256_drop(bootutil_ecdsa_p256_context *ctx) -{ - (void)ctx; -} - -static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, - uint8_t *pk, size_t pk_len, - uint8_t *hash, - uint8_t *sig, size_t sig_len) -{ - (void)ctx; - (void)pk_len; - (void)sig_len; - - /* As described on the compact representation in IETF protocols, - * the first byte of the key defines if the ECC points are - * compressed (0x2 or 0x3) or uncompressed (0x4). - * We only support uncompressed keys. - */ - if (pk[0] != 0x04) - return -1; - - pk++; - - return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, - pk, sig); -} -#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ - #ifdef __cplusplus } #endif diff --git a/boot/bootutil/include/bootutil/crypto/sha.h b/boot/bootutil/include/bootutil/crypto/sha.h index 28e827fea..9ce54bee5 100644 --- a/boot/bootutil/include/bootutil/crypto/sha.h +++ b/boot/bootutil/include/bootutil/crypto/sha.h @@ -30,7 +30,6 @@ #if (defined(MCUBOOT_USE_PSA_OR_MBED_TLS) + \ defined(MCUBOOT_USE_TINYCRYPT) + \ - defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_CC310)) != 1 #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO" #endif @@ -207,37 +206,6 @@ static inline int bootutil_sha_finish(bootutil_sha_context *ctx, } #endif /* MCUBOOT_USE_CC310 */ -#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) - -#include - -typedef bl_sha256_ctx_t bootutil_sha_context; - -static inline void bootutil_sha_init(bootutil_sha_context *ctx) -{ - bl_sha256_init(ctx); -} - -static inline void bootutil_sha_drop(bootutil_sha_context *ctx) -{ - (void)ctx; -} - -static inline int bootutil_sha_update(bootutil_sha_context *ctx, - const void *data, - uint32_t data_len) -{ - return bl_sha256_update(ctx, data, data_len); -} - -static inline int bootutil_sha_finish(bootutil_sha_context *ctx, - uint8_t *output) -{ - bl_sha256_finalize(ctx, output); - return 0; -} -#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ - #ifdef __cplusplus } #endif diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index c26633d11..382c98d9e 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -171,8 +171,6 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) zephyr_library_sources(${MCUBOOT_NRF_EXT_DIR}/cc310_glue.c) zephyr_library_include_directories(${MCUBOOT_NRF_EXT_DIR}) zephyr_link_libraries(nrfxlib_crypto) - elseif(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) - zephyr_include_directories(${BL_CRYPTO_DIR}/../include) endif() # Since here we are not using Zephyr's mbedTLS but rather our own, we need diff --git a/boot/zephyr/external_crypto.conf b/boot/zephyr/external_crypto.conf deleted file mode 100644 index 8181ad51c..000000000 --- a/boot/zephyr/external_crypto.conf +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2021 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - -# These configurations should be used when using nrf/samples/bootloader -# as the immutable bootloader (B0), and MCUBoot as the second stage updateable -# bootloader. - -# Set ECDSA as signing mechanism -CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y - -# Use crypto backend from B0 -CONFIG_BOOT_NRF_EXTERNAL_CRYPTO=y -CONFIG_SECURE_BOOT_CRYPTO=y -CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y -CONFIG_SB_CRYPTO_CLIENT_SHA256=y -CONFIG_BL_SHA256_EXT_API_REQUIRED=y -CONFIG_BL_SECP256R1_EXT_API_REQUIRED=y diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 824e83b75..2f0cc243c 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -40,8 +40,9 @@ #define MCUBOOT_USE_TINYCRYPT #elif defined(CONFIG_BOOT_USE_CC310) #define MCUBOOT_USE_CC310 -#elif defined(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) -#define MCUBOOT_USE_NRF_EXTERNAL_CRYPTO +#ifdef CONFIG_BOOT_USE_NRF_CC310_BL +#define MCUBOOT_USE_NRF_CC310_BL +#endif #endif /* Zephyr, regardless of C library used, provides snprintf */ From 2d66e666a0566843ef907035b8300af5608ca972 Mon Sep 17 00:00:00 2001 From: Mateusz Michalek Date: Mon, 20 May 2024 08:47:02 +0200 Subject: [PATCH 063/238] [nrf fromtree] boot: SHA512 verification adds TLV and Kconfig to decouple verification from other options. Signed-off-by: Mateusz Michalek Signed-off-by: Dominik Ermel (cherry picked from commit 41df52e6906172ed3398b1478e4809abfc2bc3e2) --- boot/bootutil/include/bootutil/crypto/sha.h | 15 +++-- boot/bootutil/include/bootutil/image.h | 1 + boot/bootutil/src/image_validate.c | 1 + boot/zephyr/Kconfig | 56 +++++++++++++++++++ .../include/mcuboot_config/mcuboot_config.h | 10 ++++ 5 files changed, 79 insertions(+), 4 deletions(-) diff --git a/boot/bootutil/include/bootutil/crypto/sha.h b/boot/bootutil/include/bootutil/crypto/sha.h index 9ce54bee5..28499ed6a 100644 --- a/boot/bootutil/include/bootutil/crypto/sha.h +++ b/boot/bootutil/include/bootutil/crypto/sha.h @@ -34,13 +34,16 @@ #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO" #endif -#if defined(MCUBOOT_SIGN_EC384) +#if defined(MCUBOOT_SHA512) + #define IMAGE_HASH_SIZE (64) + #define EXPECTED_HASH_TLV IMAGE_TLV_SHA512 +#elif defined(MCUBOOT_SIGN_EC384) #define IMAGE_HASH_SIZE (48) #define EXPECTED_HASH_TLV IMAGE_TLV_SHA384 #else #define IMAGE_HASH_SIZE (32) #define EXPECTED_HASH_TLV IMAGE_TLV_SHA256 -#endif /* MCUBOOT_SIGN_EC384 */ +#endif /* MCUBOOT_SIGN */ /* Universal defines for SHA-256 */ #define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64) @@ -82,7 +85,9 @@ typedef psa_hash_operation_t bootutil_sha_context; static inline int bootutil_sha_init(bootutil_sha_context *ctx) { *ctx = psa_hash_operation_init(); -#if defined(MCUBOOT_SIGN_EC384) +#if defined(MCUBOOT_SHA512) + psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_512); +#elif defined(MCUBOOT_SIGN_EC384) psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_384); #else psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_256); @@ -107,7 +112,9 @@ static inline int bootutil_sha_finish(bootutil_sha_context *ctx, { size_t hash_length = 0; /* Assumes the output buffer is at least the expected size of the hash */ -#if defined(MCUBOOT_SIGN_EC384) +#if defined(MCUBOOT_SHA512) + return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_512), &hash_length); +#elif defined(MCUBOOT_SIGN_EC384) return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_384), &hash_length); #else return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_256), &hash_length); diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 3e03f80dd..9ede800a2 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -96,6 +96,7 @@ struct flash_area; #define IMAGE_TLV_PUBKEY 0x02 /* public key */ #define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */ #define IMAGE_TLV_SHA384 0x11 /* SHA384 of image hdr and body */ +#define IMAGE_TLV_SHA512 0x12 /* SHA512 of image hdr and body */ #define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */ #define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output - Not supported anymore */ #define IMAGE_TLV_ECDSA_SIG 0x22 /* ECDSA of hash output */ diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 81782edf2..5043d385a 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -368,6 +368,7 @@ static const uint16_t allowed_unprot_tlvs[] = { IMAGE_TLV_PUBKEY, IMAGE_TLV_SHA256, IMAGE_TLV_SHA384, + IMAGE_TLV_SHA512, IMAGE_TLV_RSA2048_PSS, IMAGE_TLV_ECDSA224, IMAGE_TLV_ECDSA_SIG, diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 28f40bf52..8b35ab18c 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -27,6 +27,12 @@ config BOOT_USE_MBEDTLS help Use mbedTLS for crypto primitives. +config BOOT_USE_PSA_CRYPTO + bool + # Hidden option + help + Hidden option set if using PSA crypt for cryptography functionality + config BOOT_USE_TINYCRYPT bool # Hidden option @@ -70,6 +76,52 @@ config SINGLE_APPLICATION_SLOT uploading a new application overwrites the one that previously occupied the area. +config BOOT_IMG_HASH_ALG_SHA256_ALLOW + bool + help + Hidden option set by configurations that allow SHA256 + +config BOOT_IMG_HASH_ALG_SHA384_ALLOW + bool + help + Hidden option set by configurations that allow SHA384 + +config BOOT_IMG_HASH_ALG_SHA512_ALLOW + bool + depends on BOOT_USE_PSA_CRYPTO + help + Hidden option set by configurations that allow SHA512 + +choice BOOT_IMG_HASH_ALG + prompt "Selected image hash algorithm" + default BOOT_IMG_HASH_ALG_SHA256 if BOOT_IMG_HASH_ALG_SHA256_ALLOW + default BOOT_IMG_HASH_ALG_SHA384 if BOOT_IMG_HASH_ALG_SHA384_ALLOW + default BOOT_IMG_HASH_ALG_SHA512 if BOOT_IMG_HASH_ALG_SHA512_ALLOW + help + Hash algorithm used for image verification. Selection + here may be limited by other configurations, like for + example selected cryptographic signature. + +config BOOT_IMG_HASH_ALG_SHA256 + bool "SHA256" + depends on BOOT_IMG_HASH_ALG_SHA256_ALLOW + help + SHA256 algorithm + +config BOOT_IMG_HASH_ALG_SHA384 + bool "SHA384" + depends on BOOT_IMG_HASH_ALG_SHA384_ALLOW + help + SHA384 algorithm + +config BOOT_IMG_HASH_ALG_SHA512 + bool "SHA512" + depends on BOOT_IMG_HASH_ALG_SHA512_ALLOW + help + SHA512 algorithm + +endchoice # BOOT_IMG_HASH_ALG + choice BOOT_SIGNATURE_TYPE prompt "Signature type" default BOOT_SIGNATURE_TYPE_RSA @@ -77,12 +129,14 @@ choice BOOT_SIGNATURE_TYPE config BOOT_SIGNATURE_TYPE_NONE bool "No signature; use only hash check" select BOOT_USE_TINYCRYPT + select BOOT_IMG_HASH_ALG_SHA256_ALLOW config BOOT_SIGNATURE_TYPE_RSA bool "RSA signatures" select BOOT_USE_MBEDTLS select MBEDTLS select BOOT_ENCRYPTION_SUPPORT + select BOOT_IMG_HASH_ALG_SHA256_ALLOW if BOOT_SIGNATURE_TYPE_RSA config BOOT_SIGNATURE_TYPE_RSA_LEN @@ -94,6 +148,7 @@ endif config BOOT_SIGNATURE_TYPE_ECDSA_P256 bool "Elliptic curve digital signatures with curve P-256" select BOOT_ENCRYPTION_SUPPORT + select BOOT_IMG_HASH_ALG_SHA256_ALLOW if BOOT_SIGNATURE_TYPE_ECDSA_P256 choice BOOT_ECDSA_IMPLEMENTATION @@ -117,6 +172,7 @@ endif config BOOT_SIGNATURE_TYPE_ED25519 bool "Edwards curve digital signatures using ed25519" select BOOT_ENCRYPTION_SUPPORT + select BOOT_IMG_HASH_ALG_SHA256_ALLOW if BOOT_SIGNATURE_TYPE_ED25519 choice BOOT_ED25519_IMPLEMENTATION diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 2f0cc243c..49820ed7c 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -43,6 +43,16 @@ #ifdef CONFIG_BOOT_USE_NRF_CC310_BL #define MCUBOOT_USE_NRF_CC310_BL #endif +#elif defined(CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT) +#define MCUBOOT_USE_PSA_CRYPTO +#endif + +#ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA512 +#define MCUBOOT_SHA512 +#endif + +#ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA256 +#define MCUBOOT_SHA256 #endif /* Zephyr, regardless of C library used, provides snprintf */ From c2ff45bea3c052605f04793a41e043f5512d3af2 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Thu, 14 Feb 2019 13:20:34 +0100 Subject: [PATCH 064/238] [nrf noup] boot: Add shared crypto for ECDSA and SHA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add functions for ecdsa_verify_secp256r1 and sha256 to use the shared crypto API * Add Kconfig and CMake variables for selecting shared crypto when using ecdsa * Add custom section to project for placing the API section in the correct location in flash * Add kconfig fragment for using external crypto Signed-off-by: Sigvart Hovland Signed-off-by: Martí Bolívar Signed-off-by: Emil Obalski Signed-off-by: Andrzej Puzdrowski Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Trond Einar Snekvik Signed-off-by: Georgios Vasilakis Signed-off-by: Johann Fischer Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 55683e3133b6a801a7bb7feb55d24be81ecccdbb) (cherry picked from commit 0faa8b2bb51bd58c9a1d3470f78f7b4136999652) (cherry picked from commit a42e9cc5fa46b614e60353d6a255984f72ab4d7e) (cherry picked from commit 895c76beb540d91cd9ddb53198bbfde0089c36d4) (cherry picked from commit ff5338297c4be31e757f99d8cf5730b05a5cbed6) (cherry picked from commit cc42516352e797433e6e0413fc41e08d2b583739) --- boot/bootutil/include/bootutil/crypto/ecdsa.h | 64 +++++++++++++++++-- boot/bootutil/include/bootutil/crypto/sha.h | 32 ++++++++++ boot/zephyr/CMakeLists.txt | 2 + boot/zephyr/external_crypto.conf | 20 ++++++ .../include/mcuboot_config/mcuboot_config.h | 5 +- 5 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 boot/zephyr/external_crypto.conf diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index 5a87f736b..450450dc3 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -34,6 +34,7 @@ #if (defined(MCUBOOT_USE_TINYCRYPT) + \ defined(MCUBOOT_USE_CC310) + \ + defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_PSA_OR_MBED_TLS)) != 1 #error "One crypto backend must be defined: either CC310/TINYCRYPT/MBED_TLS/PSA_CRYPTO" #endif @@ -70,12 +71,18 @@ #include "bootutil/sign_key.h" #include "common.h" +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + #include + #define NUM_ECC_BYTES (256 / 8) +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus extern "C" { #endif #if (defined(MCUBOOT_USE_TINYCRYPT) || defined(MCUBOOT_USE_MBED_TLS) || \ - defined(MCUBOOT_USE_CC310)) && !defined(MCUBOOT_USE_PSA_CRYPTO) + defined(MCUBOOT_USE_CC310) || defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO)) \ + && !defined(MCUBOOT_USE_PSA_CRYPTO) /* * Declaring these like this adds NULL termination. */ @@ -127,8 +134,6 @@ static int bootutil_import_key(uint8_t **cp, uint8_t *end) } #endif /* (MCUBOOT_USE_TINYCRYPT || MCUBOOT_USE_MBED_TLS || MCUBOOT_USE_CC310) && !MCUBOOT_USE_PSA_CRYPTO */ -#if defined(MCUBOOT_USE_TINYCRYPT) -#ifndef MCUBOOT_ECDSA_NEED_ASN1_SIG /* * cp points to ASN1 string containing an integer. * Verify the tag, and that the length is 32 bytes. Helper function. @@ -178,8 +183,8 @@ static int bootutil_decode_sig(uint8_t signature[NUM_ECC_BYTES * 2], uint8_t *cp } return 0; } -#endif /* not MCUBOOT_ECDSA_NEED_ASN1_SIG */ +#if defined(MCUBOOT_USE_TINYCRYPT) typedef uintptr_t bootutil_ecdsa_context; static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) { @@ -248,8 +253,12 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, { (void)ctx; (void)pk_len; - (void)sig_len; (void)hash_len; + uint8_t dsig[2 * NUM_ECC_BYTES]; + + if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { + return -1; + } /* Only support uncompressed keys. */ if (pk[0] != 0x04) { @@ -257,7 +266,7 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, } pk++; - return cc310_ecdsa_verify_secp256r1(hash, pk, sig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); + return cc310_ecdsa_verify_secp256r1(hash, pk, dsig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); } static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, @@ -613,6 +622,49 @@ static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, #endif /* MCUBOOT_USE_MBED_TLS */ +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) +typedef uintptr_t bootutil_ecdsa_context; +static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) +{ + (void)ctx; +} + +static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx) +{ + (void)ctx; +} + +static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, + uint8_t *pk, size_t pk_len, + uint8_t *hash, size_t hash_len, + uint8_t *sig, size_t sig_len) +{ + (void)ctx; + (void)pk_len; + (void)hash_len; + uint8_t dsig[2 * NUM_ECC_BYTES]; + + if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { + return -1; + } + + /* Only support uncompressed keys. */ + if (pk[0] != 0x04) { + return -1; + } + pk++; + + return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, pk, dsig); +} + +static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, + uint8_t **cp,uint8_t *end) +{ + (void)ctx; + return bootutil_import_key(cp, end); +} +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus } #endif diff --git a/boot/bootutil/include/bootutil/crypto/sha.h b/boot/bootutil/include/bootutil/crypto/sha.h index 28499ed6a..aeedff40e 100644 --- a/boot/bootutil/include/bootutil/crypto/sha.h +++ b/boot/bootutil/include/bootutil/crypto/sha.h @@ -30,6 +30,7 @@ #if (defined(MCUBOOT_USE_PSA_OR_MBED_TLS) + \ defined(MCUBOOT_USE_TINYCRYPT) + \ + defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_CC310)) != 1 #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO" #endif @@ -213,6 +214,37 @@ static inline int bootutil_sha_finish(bootutil_sha_context *ctx, } #endif /* MCUBOOT_USE_CC310 */ +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + +#include + +typedef bl_sha256_ctx_t bootutil_sha_context; + +static inline void bootutil_sha_init(bootutil_sha_context *ctx) +{ + bl_sha256_init(ctx); +} + +static inline void bootutil_sha_drop(bootutil_sha_context *ctx) +{ + (void)ctx; +} + +static inline int bootutil_sha_update(bootutil_sha_context *ctx, + const void *data, + uint32_t data_len) +{ + return bl_sha256_update(ctx, data, data_len); +} + +static inline int bootutil_sha_finish(bootutil_sha_context *ctx, + uint8_t *output) +{ + bl_sha256_finalize(ctx, output); + return 0; +} +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus } #endif diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 382c98d9e..c26633d11 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -171,6 +171,8 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) zephyr_library_sources(${MCUBOOT_NRF_EXT_DIR}/cc310_glue.c) zephyr_library_include_directories(${MCUBOOT_NRF_EXT_DIR}) zephyr_link_libraries(nrfxlib_crypto) + elseif(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) + zephyr_include_directories(${BL_CRYPTO_DIR}/../include) endif() # Since here we are not using Zephyr's mbedTLS but rather our own, we need diff --git a/boot/zephyr/external_crypto.conf b/boot/zephyr/external_crypto.conf new file mode 100644 index 000000000..8181ad51c --- /dev/null +++ b/boot/zephyr/external_crypto.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# These configurations should be used when using nrf/samples/bootloader +# as the immutable bootloader (B0), and MCUBoot as the second stage updateable +# bootloader. + +# Set ECDSA as signing mechanism +CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y + +# Use crypto backend from B0 +CONFIG_BOOT_NRF_EXTERNAL_CRYPTO=y +CONFIG_SECURE_BOOT_CRYPTO=y +CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y +CONFIG_SB_CRYPTO_CLIENT_SHA256=y +CONFIG_BL_SHA256_EXT_API_REQUIRED=y +CONFIG_BL_SECP256R1_EXT_API_REQUIRED=y diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 49820ed7c..9d58436d2 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -40,11 +40,10 @@ #define MCUBOOT_USE_TINYCRYPT #elif defined(CONFIG_BOOT_USE_CC310) #define MCUBOOT_USE_CC310 -#ifdef CONFIG_BOOT_USE_NRF_CC310_BL -#define MCUBOOT_USE_NRF_CC310_BL -#endif #elif defined(CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT) #define MCUBOOT_USE_PSA_CRYPTO +#elif defined(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) +#define MCUBOOT_USE_NRF_EXTERNAL_CRYPTO #endif #ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA512 From 5e33dacb69c7989e5fe07646d7c14c9b4d49e77b Mon Sep 17 00:00:00 2001 From: Rustam Ismayilov Date: Mon, 27 Nov 2023 21:44:54 +0100 Subject: [PATCH 065/238] [nrf fromtree] imgtool: Fix verify command for edcsa-p384 signed images Fixed hash algorithm defaults to SHA256 in case no key provided. Verification improved by adding check for key - tlv mismatch, VerifyResult.KEY_MISMATCH added to indicate this case. Multiple styling fixes and import optimisation, exception handling. Signed-off-by: Rustam Ismayilov Change-Id: I61a588de5b39678707c0179f4edaa411ceb67c8e (cherry picked from commit 36f8bf3085cd013b0abdd29331d08c9bbe796ca9) Signed-off-by: Dominik Ermel --- scripts/imgtool/image.py | 101 ++++++++++++++++++++++----------------- scripts/imgtool/main.py | 2 + 2 files changed, 58 insertions(+), 45 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index 3de8357a6..a30d53bf2 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -1,6 +1,6 @@ # Copyright 2018 Nordic Semiconductor ASA # Copyright 2017-2020 Linaro Limited -# Copyright 2019-2023 Arm Limited +# Copyright 2019-2024 Arm Limited # # SPDX-License-Identifier: Apache-2.0 # @@ -20,23 +20,25 @@ Image signing and management. """ -from . import version as versmod -from .boot_record import create_sw_component_data -import click -from enum import Enum -from intelhex import IntelHex import hashlib -import struct import os.path -from .keys import rsa, ecdsa, x25519 +import struct +from enum import Enum + +import click +from cryptography.exceptions import InvalidSignature +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes, hmac from cryptography.hazmat.primitives.asymmetric import ec, padding from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives.kdf.hkdf import HKDF from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import hashes, hmac -from cryptography.exceptions import InvalidSignature +from intelhex import IntelHex + +from . import version as versmod, keys +from .boot_record import create_sw_component_data +from .keys import rsa, ecdsa, x25519 IMAGE_MAGIC = 0x96f3b83d IMAGE_HEADER_SIZE = 32 @@ -90,10 +92,8 @@ } VerifyResult = Enum('VerifyResult', - """ - OK INVALID_MAGIC INVALID_TLV_INFO_MAGIC INVALID_HASH - INVALID_SIGNATURE - """) + ['OK', 'INVALID_MAGIC', 'INVALID_TLV_INFO_MAGIC', 'INVALID_HASH', 'INVALID_SIGNATURE', + 'KEY_MISMATCH']) def align_up(num, align): @@ -135,7 +135,24 @@ def get(self): return header + bytes(self.buf) -class Image(): +def get_digest(tlv_type, hash_region): + if tlv_type == TLV_VALUES["SHA384"]: + sha = hashlib.sha384() + elif tlv_type == TLV_VALUES["SHA256"]: + sha = hashlib.sha256() + + sha.update(hash_region) + return sha.digest() + + +def tlv_matches_key_type(tlv_type, key): + """Check if provided key matches to TLV record in the image""" + return (key is None or + type(key) == keys.ECDSA384P1 and tlv_type == TLV_VALUES["SHA384"] or + type(key) != keys.ECDSA384P1 and tlv_type == TLV_VALUES["SHA256"]) + + +class Image: def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, pad_header=False, pad=False, confirm=False, align=1, @@ -178,9 +195,9 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, msb = (self.max_align & 0xff00) >> 8 align = bytes([msb, lsb]) if self.endian == "big" else bytes([lsb, msb]) self.boot_magic = align + bytes([0x2d, 0xe1, - 0x5d, 0x29, 0x41, 0x0b, - 0x8d, 0x77, 0x67, 0x9c, - 0x11, 0x0f, 0x1f, 0x8a, ]) + 0x5d, 0x29, 0x41, 0x0b, + 0x8d, 0x77, 0x67, 0x9c, + 0x11, 0x0f, 0x1f, 0x8a, ]) if security_counter == 'auto': # Security counter has not been explicitly provided, @@ -321,9 +338,8 @@ def create(self, key, public_key_format, enckey, dependencies=None, self.enckey = enckey # Check what hashing algorithm should be used - if (key is not None and isinstance(key, ecdsa.ECDSA384P1) or - pub_key is not None and isinstance(pub_key, - ecdsa.ECDSA384P1Public)): + if (key and isinstance(key, ecdsa.ECDSA384P1) + or pub_key and isinstance(pub_key, ecdsa.ECDSA384P1Public)): hash_algorithm = hashlib.sha384 hash_tlv = "SHA384" else: @@ -430,13 +446,13 @@ def create(self, key, public_key_format, enckey, dependencies=None, if dependencies is not None: for i in range(dependencies_num): payload = struct.pack( - e + 'B3x'+'BBHI', - int(dependencies[DEP_IMAGES_KEY][i]), - dependencies[DEP_VERSIONS_KEY][i].major, - dependencies[DEP_VERSIONS_KEY][i].minor, - dependencies[DEP_VERSIONS_KEY][i].revision, - dependencies[DEP_VERSIONS_KEY][i].build - ) + e + 'B3x' + 'BBHI', + int(dependencies[DEP_IMAGES_KEY][i]), + dependencies[DEP_VERSIONS_KEY][i].major, + dependencies[DEP_VERSIONS_KEY][i].minor, + dependencies[DEP_VERSIONS_KEY][i].revision, + dependencies[DEP_VERSIONS_KEY][i].build + ) prot_tlv.add('DEPENDENCY', payload) if custom_tlvs is not None: @@ -640,42 +656,37 @@ def verify(imgfile, key): return VerifyResult.INVALID_MAGIC, None, None tlv_off = header_size + img_size - tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE] + tlv_info = b[tlv_off:tlv_off + TLV_INFO_SIZE] magic, tlv_tot = struct.unpack('HH', tlv_info) if magic == TLV_PROT_INFO_MAGIC: tlv_off += tlv_tot - tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE] + tlv_info = b[tlv_off:tlv_off + TLV_INFO_SIZE] magic, tlv_tot = struct.unpack('HH', tlv_info) if magic != TLV_INFO_MAGIC: return VerifyResult.INVALID_TLV_INFO_MAGIC, None, None - if isinstance(key, ecdsa.ECDSA384P1Public): - sha = hashlib.sha384() - hash_tlv = "SHA384" - else: - sha = hashlib.sha256() - hash_tlv = "SHA256" - prot_tlv_size = tlv_off - sha.update(b[:prot_tlv_size]) - digest = sha.digest() - + hash_region = b[:prot_tlv_size] + digest = None tlv_end = tlv_off + tlv_tot tlv_off += TLV_INFO_SIZE # skip tlv info while tlv_off < tlv_end: - tlv = b[tlv_off:tlv_off+TLV_SIZE] + tlv = b[tlv_off:tlv_off + TLV_SIZE] tlv_type, _, tlv_len = struct.unpack('BBH', tlv) - if tlv_type == TLV_VALUES[hash_tlv]: + if tlv_type == TLV_VALUES["SHA256"] or tlv_type == TLV_VALUES["SHA384"]: + if not tlv_matches_key_type(tlv_type, key): + return VerifyResult.KEY_MISMATCH, None, None off = tlv_off + TLV_SIZE - if digest == b[off:off+tlv_len]: + digest = get_digest(tlv_type, hash_region) + if digest == b[off:off + tlv_len]: if key is None: return VerifyResult.OK, version, digest else: return VerifyResult.INVALID_HASH, None, None elif key is not None and tlv_type == TLV_VALUES[key.sig_tlv()]: off = tlv_off + TLV_SIZE - tlv_sig = b[off:off+tlv_len] + tlv_sig = b[off:off + tlv_len] payload = b[:prot_tlv_size] try: if hasattr(key, 'verify'): diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index e24c9a087..f70a8bf51 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -228,6 +228,8 @@ def verify(key, imgfile): print("Image has an invalid hash") elif ret == image.VerifyResult.INVALID_SIGNATURE: print("No signature found for the given key") + elif ret == image.VerifyResult.KEY_MISMATCH: + print("Key type does not match TLV record") else: print("Unknown return code: {}".format(ret)) sys.exit(1) From 300c41cd4258478036adf77c42662b9d51170330 Mon Sep 17 00:00:00 2001 From: Mateusz Wielgos Date: Mon, 26 Feb 2024 15:02:45 -0600 Subject: [PATCH 066/238] [nrf fromtree] imgtool: Add --non-bootable flag Defaults to false. Signed-off-by: Mateusz Wielgos (cherry picked from commit dc03055537f2e835e3905e7853f0a1fc0b70a57e) Signed-off-by: Dominik Ermel --- scripts/imgtool/image.py | 6 +++++- scripts/imgtool/main.py | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index a30d53bf2..5c4732b53 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -159,7 +159,8 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, slot_size=0, max_sectors=DEFAULT_MAX_SECTORS, overwrite_only=False, endian="little", load_addr=0, rom_fixed=None, erased_val=None, save_enctlv=False, - security_counter=None, max_align=None): + security_counter=None, max_align=None, + non_bootable=False): if load_addr and rom_fixed: raise click.UsageError("Can not set rom_fixed and load_addr at the same time") @@ -183,6 +184,7 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, self.save_enctlv = save_enctlv self.enctlv_len = 0 self.max_align = max(DEFAULT_MAX_ALIGN, align) if max_align is None else int(max_align) + self.non_bootable = non_bootable if self.max_align == DEFAULT_MAX_ALIGN: self.boot_magic = bytes([ @@ -567,6 +569,8 @@ def add_header(self, enckey, protected_tlv_size, aes_length=128): flags |= IMAGE_F['RAM_LOAD'] if self.rom_fixed: flags |= IMAGE_F['ROM_FIXED'] + if self.non_bootable: + flags |= IMAGE_F['NON_BOOTABLE'] e = STRUCT_ENDIAN_DICT[self.endian] fmt = (e + diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index f70a8bf51..cc2cf9c58 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -314,6 +314,8 @@ def convert(self, value, param, ctx): @click.argument('outfile') @click.argument('infile') +@click.option('--non-bootable', default=False, is_flag=True, + help='Mark the image as non-bootable.') @click.option('--custom-tlv', required=False, nargs=2, default=[], multiple=True, metavar='[tag] [value]', help='Custom TLV that will be placed into protected area. ' @@ -411,7 +413,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, endian, encrypt_keylen, encrypt, infile, outfile, dependencies, load_addr, hex_addr, erased_val, save_enctlv, security_counter, boot_record, custom_tlv, rom_fixed, max_align, clear, fix_sig, - fix_sig_pubkey, sig_out, vector_to_sign): + fix_sig_pubkey, sig_out, vector_to_sign, non_bootable): if confirm: # Confirmed but non-padded images don't make much sense, because @@ -423,7 +425,8 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, max_sectors=max_sectors, overwrite_only=overwrite_only, endian=endian, load_addr=load_addr, rom_fixed=rom_fixed, erased_val=erased_val, save_enctlv=save_enctlv, - security_counter=security_counter, max_align=max_align) + security_counter=security_counter, max_align=max_align, + non_bootable=non_bootable) img.load(infile) key = load_key(key) if key else None enckey = load_key(encrypt) if encrypt else None From 7aaeb636812f7e5b0b901a1894916dbfd5334f3a Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 22 Aug 2024 14:58:15 +0000 Subject: [PATCH 067/238] [nrf fromlist] imgtool: Add support for calculating SHA512 The adds support for hashing image with SHA512, to allow SHA512-ED25519-SHA512 signature. To support above --sha parameter has been added that can take value: auto, 256, 384, 512 to select sha, where auto brings the default behaviour, or current, behaviour. The sha provided here is tested against key so not all combinations are supported. Upstream PR: https://github.com/mcu-tools/mcuboot/pull/2048 Signed-off-by: Dominik Ermel --- scripts/imgtool/image.py | 111 ++++++++++++++++++++++++++++++++------- scripts/imgtool/main.py | 8 ++- 2 files changed, 97 insertions(+), 22 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index 5c4732b53..53b19ef1d 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -40,6 +40,8 @@ from .boot_record import create_sw_component_data from .keys import rsa, ecdsa, x25519 +from collections import namedtuple + IMAGE_MAGIC = 0x96f3b83d IMAGE_HEADER_SIZE = 32 BIN_EXT = "bin" @@ -65,6 +67,7 @@ 'PUBKEY': 0x02, 'SHA256': 0x10, 'SHA384': 0x11, + 'SHA512': 0x12, 'RSA2048': 0x20, 'ECDSASIG': 0x22, 'RSA3072': 0x23, @@ -135,11 +138,73 @@ def get(self): return header + bytes(self.buf) +SHAAndAlgT = namedtuple('SHAAndAlgT', ['sha', 'alg']) + +TLV_SHA_TO_SHA_AND_ALG = { + TLV_VALUES['SHA256'] : SHAAndAlgT('256', hashlib.sha256), + TLV_VALUES['SHA384'] : SHAAndAlgT('384', hashlib.sha384), + TLV_VALUES['SHA512'] : SHAAndAlgT('512', hashlib.sha512), +} + + +USER_SHA_TO_ALG_AND_TLV = { + 'auto' : (hashlib.sha256, 'SHA256'), + '256' : (hashlib.sha256, 'SHA256'), + '384' : (hashlib.sha384, 'SHA384'), + '512' : (hashlib.sha512, 'SHA512') +} + + +def is_sha_tlv(tlv): + return tlv in TLV_SHA_TO_SHA_AND_ALG.keys() + + +def tlv_sha_to_sha(tlv): + return TLV_SHA_TO_SHA_AND_ALG[tlv].sha + + +# Auto selecting hash algorithm for type(key) +ALLOWED_KEY_SHA = { + keys.ECDSA384P1 : ['384'], + keys.ECDSA384P1Public : ['384'], + keys.ECDSA256P1 : ['256'], + keys.RSA : ['256'], + # This two are set to 256 for compatibility, the right would be 512 + keys.Ed25519 : ['256', '512'], + keys.X25519 : ['256', '512'] +} + +def key_and_user_sha_to_alg_and_tlv(key, user_sha): + """Matches key and user requested sha to sha alogrithm and TLV name. + + The returned tuple will contain hash functions and TVL name. + The function is designed to succeed or completely fail execution, + as providing incorrect pair here basically prevents doing + any more work. + """ + if key is None: + # If key is none, we allow whatever user has selected for sha + return USER_SHA_TO_ALG_AND_TLV[user_sha] + + # If key is not None, then we have to filter hash to only allowed + allowed = None + try: + allowed = ALLOWED_KEY_SHA[type(key)] + except KeyError: + raise click.UsageError("Colud not find allowed hash algorithms for {}" + .format(type(key))) + if user_sha == 'auto': + return USER_SHA_TO_ALG_AND_TLV[allowed[0]] + + if user_sha in allowed: + return USER_SHA_TO_ALG_AND_TLV[user_sha] + + raise click.UsageError("Key {} can not be used with --sha {}; allowed sha are one of {}" + .format(key.sig_type(), user_sha, allowed)) + + def get_digest(tlv_type, hash_region): - if tlv_type == TLV_VALUES["SHA384"]: - sha = hashlib.sha384() - elif tlv_type == TLV_VALUES["SHA256"]: - sha = hashlib.sha256() + sha = TLV_SHA_TO_SHA_AND_ALG[tlv_type].alg() sha.update(hash_region) return sha.digest() @@ -147,9 +212,16 @@ def get_digest(tlv_type, hash_region): def tlv_matches_key_type(tlv_type, key): """Check if provided key matches to TLV record in the image""" - return (key is None or - type(key) == keys.ECDSA384P1 and tlv_type == TLV_VALUES["SHA384"] or - type(key) != keys.ECDSA384P1 and tlv_type == TLV_VALUES["SHA256"]) + try: + # We do not need the result here, and the key_and_user_sha_to_alg_and_tlv + # will either succeed finding match or rise exception, so on success we + # return True, on exception we return False. + _, _ = key_and_user_sha_to_alg_and_tlv(key, tlv_sha_to_sha(tlv_type)) + return True + except: + pass + + return False class Image: @@ -336,17 +408,13 @@ def ecies_hkdf(self, enckey, plainkey): def create(self, key, public_key_format, enckey, dependencies=None, sw_type=None, custom_tlvs=None, encrypt_keylen=128, clear=False, - fixed_sig=None, pub_key=None, vector_to_sign=None): + fixed_sig=None, pub_key=None, vector_to_sign=None, user_sha='auto'): self.enckey = enckey - # Check what hashing algorithm should be used - if (key and isinstance(key, ecdsa.ECDSA384P1) - or pub_key and isinstance(pub_key, ecdsa.ECDSA384P1Public)): - hash_algorithm = hashlib.sha384 - hash_tlv = "SHA384" - else: - hash_algorithm = hashlib.sha256 - hash_tlv = "SHA256" + # key decides on sha, then pub_key; of both are none default is used + check_key = key if key is not None else pub_key + hash_algorithm, hash_tlv = key_and_user_sha_to_alg_and_tlv(check_key, user_sha) + # Calculate the hash of the public key if key is not None: pub = key.get_public_bytes() @@ -466,11 +534,14 @@ def create(self, key, public_key_format, enckey, dependencies=None, tlv = TLV(self.endian) - # Note that ecdsa wants to do the hashing itself, which means - # we get to hash it twice. + # These signature is done over sha of image. In case of + # EC signatures so called Pure algorithm, designated to be run + # over entire message is used with sha of image as message, + # so, for example, in case of ED25519 we have here SHAxxx-ED25519-SHA512. sha = hash_algorithm() sha.update(self.payload) digest = sha.digest() + message = digest; tlv.add(hash_tlv, digest) if vector_to_sign == 'payload': @@ -499,7 +570,7 @@ def create(self, key, public_key_format, enckey, dependencies=None, sig = key.sign(bytes(self.payload)) else: print(os.path.basename(__file__) + ": sign the digest") - sig = key.sign_digest(digest) + sig = key.sign_digest(message) tlv.add(key.sig_tlv(), sig) self.signature = sig elif fixed_sig is not None and key is None: @@ -678,7 +749,7 @@ def verify(imgfile, key): while tlv_off < tlv_end: tlv = b[tlv_off:tlv_off + TLV_SIZE] tlv_type, _, tlv_len = struct.unpack('BBH', tlv) - if tlv_type == TLV_VALUES["SHA256"] or tlv_type == TLV_VALUES["SHA384"]: + if is_sha_tlv(tlv_type): if not tlv_matches_key_type(tlv_type, key): return VerifyResult.KEY_MISMATCH, None, None off = tlv_off + TLV_SIZE diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index cc2cf9c58..848fd3110 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -72,6 +72,7 @@ def gen_x25519(keyfile, passwd): 'x25519': gen_x25519, } valid_formats = ['openssl', 'pkcs8'] +valid_sha = [ 'auto', '256', '384', '512' ] def load_signature(sigfile): @@ -401,6 +402,9 @@ def convert(self, value, param, ctx): @click.option('--sig-out', metavar='filename', help='Path to the file to which signature will be written. ' 'The image signature will be encoded as base64 formatted string') +@click.option('--sha', 'user_sha', type=click.Choice(valid_sha), default='auto', + help='selected sha algorithm to use; defaults to "auto" which is 256 if ' + 'no cryptographic signature is used, or default for signature type') @click.option('--vector-to-sign', type=click.Choice(['payload', 'digest']), help='send to OUTFILE the payload or payload''s digest instead ' 'of complied image. These data can be used for external image ' @@ -413,7 +417,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, endian, encrypt_keylen, encrypt, infile, outfile, dependencies, load_addr, hex_addr, erased_val, save_enctlv, security_counter, boot_record, custom_tlv, rom_fixed, max_align, clear, fix_sig, - fix_sig_pubkey, sig_out, vector_to_sign, non_bootable): + fix_sig_pubkey, sig_out, user_sha, vector_to_sign, non_bootable): if confirm: # Confirmed but non-padded images don't make much sense, because @@ -481,7 +485,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, img.create(key, public_key_format, enckey, dependencies, boot_record, custom_tlvs, int(encrypt_keylen), clear, baked_signature, - pub_key, vector_to_sign) + pub_key, vector_to_sign, user_sha) img.save(outfile, hex_addr) if sig_out is not None: From 647a928315b7e004e663d60b92c198e668b90b41 Mon Sep 17 00:00:00 2001 From: David Brown Date: Thu, 27 Jun 2024 11:13:01 -0600 Subject: [PATCH 068/238] [nrf fromtree] boot: Fix ASN.1 for mbedtls >= 3.1 In Mbed TLS 3.1, the private fields in the ASN.1 structure were made private. This breaks code that accesses these private macros. Fix this by changing the ASN.1 specific code to use a new field accessor `ASN1_CONTEXT_MEMBER` that will be conditionally defined based on the version of Mbed TLS that is present. Signed-off-by: David Brown (cherry picked from commit 1d79ef35ee560e24da981d13c9414de9947b07a2) Signed-off-by: Dominik Ermel --- boot/bootutil/include/bootutil/crypto/common.h | 9 +++++++++ boot/bootutil/include/bootutil/crypto/ecdsa.h | 16 ++++++++-------- boot/bootutil/src/encrypted.c | 12 ++++++------ boot/bootutil/src/image_ed25519.c | 4 ++-- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/boot/bootutil/include/bootutil/crypto/common.h b/boot/bootutil/include/bootutil/crypto/common.h index c765fe1f3..1fb5c5835 100644 --- a/boot/bootutil/include/bootutil/crypto/common.h +++ b/boot/bootutil/include/bootutil/crypto/common.h @@ -17,4 +17,13 @@ #define MBEDTLS_CONTEXT_MEMBER(X) X #endif +/* Newer versions of Mbed TLS have removed the private accessor requirement for + * the ASN1 fields. + */ +#if (MBEDTLS_VERSION_NUMBER >= 0x03000000) && (MBEDTLS_VERSION_NUMBER < 0x03010000) +#define ASN1_CONTEXT_MEMBER(X) MBEDTLS_PRIVATE(X) +#else +#define ASN1_CONTEXT_MEMBER(X) X +#endif + #endif /* __BOOTUTIL_CRYPTO_COMMON_H__ */ diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index 450450dc3..85355f20c 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -109,13 +109,13 @@ static int bootutil_import_key(uint8_t **cp, uint8_t *end) return -2; } /* id-ecPublicKey (RFC5480) */ - if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || - memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { + if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || + memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { return -3; } /* namedCurve (RFC5480) */ - if (param.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 || - memcmp(param.MBEDTLS_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { + if (param.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 || + memcmp(param.ASN1_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { return -4; } /* ECPoint (RFC5480) */ @@ -521,12 +521,12 @@ static int bootutil_parse_eckey(bootutil_ecdsa_context *ctx, uint8_t **p, uint8_ if (mbedtls_asn1_get_alg(p, end, &alg, ¶m)) { return -2; } - if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || - memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { + if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || + memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { return -3; } - if (param.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1|| - memcmp(param.MBEDTLS_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { + if (param.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1|| + memcmp(param.ASN1_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { return -4; } diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index 39e34dbd3..212774e3a 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -126,12 +126,12 @@ parse_ec256_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key) return -5; } - if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || - memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { + if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || + memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { return -6; } - if (param.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 || - memcmp(param.MBEDTLS_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { + if (param.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 || + memcmp(param.ASN1_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { return -7; } @@ -203,8 +203,8 @@ parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key) return -4; } - if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || - memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { + if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || + memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { return -5; } diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index c51fea494..7a597d4c0 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -45,8 +45,8 @@ bootutil_import_key(uint8_t **cp, uint8_t *end) return -2; } - if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ed25519_pubkey_oid) - 1 || - memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ed25519_pubkey_oid, sizeof(ed25519_pubkey_oid) - 1)) { + if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ed25519_pubkey_oid) - 1 || + memcmp(alg.ASN1_CONTEXT_MEMBER(p), ed25519_pubkey_oid, sizeof(ed25519_pubkey_oid) - 1)) { return -3; } From 3a8716bbe8783227e7cc5f05f901c8cffd735fca Mon Sep 17 00:00:00 2001 From: Thomas Altenbach Date: Thu, 25 Apr 2024 15:29:21 +0200 Subject: [PATCH 069/238] [nrf fromtree] bootutil: Keep image encrypted in scratch area Currently, when swap using scratch is used with encrypted images, MCUboot is decrypting the images during the copy from the secondary slot to the scratch area. This means the scratch area contains plaintext image data and therefore that the scratch area must be placed in the MCU's internal flash memory. This commit makes the necessary changes to perform the decryption when copying from the scratch area to the primary slot instead, making possible to place the scratch area in an external flash memory since the scratch area is now encrypted. Note that BOOT_SWAP_SAVE_ENCTLV must be enabled if the scratch area is placed in external flash memory. Signed-off-by: Thomas Altenbach (cherry picked from commit 08d2d94c144917732c727179d51feaef26e8c1b1) Signed-off-by: Dominik Ermel --- boot/boot_serial/src/boot_serial_encryption.c | 2 +- boot/bootutil/include/bootutil/enc_key.h | 2 +- boot/bootutil/src/encrypted.c | 4 +- boot/bootutil/src/image_validate.c | 2 +- boot/bootutil/src/loader.c | 38 +++++++++---------- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index 6201e6b69..51d25024e 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -175,7 +175,7 @@ decrypt_region_inplace(struct boot_loader_state *state, blk_sz = tlv_off - (off + bytes_copied); } } - boot_encrypt(BOOT_CURR_ENC(state), image_index, fap, + boot_encrypt(BOOT_CURR_ENC(state), image_index, flash_area_get_id(fap), (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index 768dd8e7e..d8dab9013 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -59,7 +59,7 @@ int boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey); bool boot_enc_valid(struct enc_key_data *enc_state, int image_index, const struct flash_area *fap); void boot_encrypt(struct enc_key_data *enc_state, int image_index, - const struct flash_area *fap, uint32_t off, uint32_t sz, + int fa_id, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); void boot_enc_zeroize(struct enc_key_data *enc_state); diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index 212774e3a..44975cc49 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -681,7 +681,7 @@ boot_enc_valid(struct enc_key_data *enc_state, int image_index, void boot_encrypt(struct enc_key_data *enc_state, int image_index, - const struct flash_area *fap, uint32_t off, uint32_t sz, + int fa_id, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf) { struct enc_key_data *enc; @@ -701,7 +701,7 @@ boot_encrypt(struct enc_key_data *enc_state, int image_index, nonce[14] = (uint8_t)(off >> 8); nonce[15] = (uint8_t)off; - rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fap)); + rc = flash_area_id_to_multi_image_slot(image_index, fa_id); if (rc < 0) { assert(0); return; diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 5043d385a..09b8082ec 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -159,7 +159,7 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, /* Only payload is encrypted (area between header and TLVs) */ if (off >= hdr_size && off < tlv_off) { blk_off = (off - hdr_size) & 0xf; - boot_encrypt(enc_state, image_index, fap, off - hdr_size, + boot_encrypt(enc_state, image_index, flash_area_get_id(fap), off - hdr_size, blk_sz, blk_off, tmp_buf); } } diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index d35b6910c..4a93b8dbd 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1576,10 +1576,13 @@ boot_copy_region(struct boot_loader_state *state, uint32_t off; uint32_t tlv_off; size_t blk_off; + int enc_area_id; struct image_header *hdr; uint16_t idx; uint32_t blk_sz; uint8_t image_index; + bool encrypted_src; + bool encrypted_dst; #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES struct image_header *hdr; @@ -1616,25 +1619,22 @@ boot_copy_region(struct boot_loader_state *state, #ifdef MCUBOOT_ENC_IMAGES image_index = BOOT_CURR_IMG(state); - if ((flash_area_get_id(fap_src) == FLASH_AREA_IMAGE_SECONDARY(image_index) || - flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index)) && - !(flash_area_get_id(fap_src) == FLASH_AREA_IMAGE_SECONDARY(image_index) && - flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index))) { - /* assume the secondary slot as src, needs decryption */ - hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); -#if !defined(MCUBOOT_SWAP_USING_MOVE) - off = off_src; - if (flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index)) { - /* might need encryption (metadata from the primary slot) */ - hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT); - off = off_dst; - } -#else + encrypted_src = (flash_area_get_id(fap_src) != FLASH_AREA_IMAGE_PRIMARY(image_index)); + encrypted_dst = (flash_area_get_id(fap_dst) != FLASH_AREA_IMAGE_PRIMARY(image_index)); + + if (encrypted_src != encrypted_dst) { off = off_dst; - if (flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index)) { + + if (encrypted_dst) { + /* Need encryption, metadata from the primary slot */ hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT); + enc_area_id = FLASH_AREA_IMAGE_PRIMARY(image_index); + } else { + /* Need decryption, metadata from the secondary slot */ + hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + enc_area_id = FLASH_AREA_IMAGE_SECONDARY(image_index); } -#endif + if (IS_ENCRYPTED(hdr)) { uint32_t abs_off = off + bytes_copied; if (abs_off < hdr->ih_hdr_size) { @@ -1665,7 +1665,7 @@ boot_copy_region(struct boot_loader_state *state, blk_sz = tlv_off - abs_off; } } - boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src, + boot_encrypt(BOOT_CURR_ENC(state), image_index, enc_area_id, (abs_off + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } @@ -3175,13 +3175,13 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, * Part of the chunk is encrypted payload */ blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf; blk_sz = tlv_off - (bytes_copied); - boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src, + boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, cur_dst); } else { /* Image encrypted payload section */ blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf; - boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src, + boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, cur_dst); } From eb5042bf352bf288ed197ef8fcca504eaef4cf31 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 12 Jul 2024 19:44:46 +0000 Subject: [PATCH 070/238] [nrf fromtree] boot: Remove pointless slot identification In the boot_image_validate_encrypted there was call to flash_area_id_to_multi_image_slot, which tries to figure out slot index from flash area and image index, and the result of the call was not used for anything as slot index is hardcoded in the next call to be 1 (secondary). Signed-off-by: Dominik Ermel (cherry picked from commit 4da4a72cb15f0e90cf7c2de24a48f54721e86ded) --- boot/boot_serial/src/boot_serial_encryption.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index 51d25024e..6717826f1 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -40,10 +40,6 @@ boot_image_validate_encrypted(const struct flash_area *fa_p, if (rc < 0) { FIH_RET(fih_rc); } - rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fa_p)); - if (rc < 0) { - FIH_RET(fih_rc); - } rc = boot_enc_set_key(BOOT_CURR_ENC(state), 1, bs); if (rc < 0) { FIH_RET(fih_rc); From dd38c001851caa797c01d95193a11ebbc3cb8a2f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 12 Jul 2024 17:43:13 +0000 Subject: [PATCH 071/238] [nrf fromtree] boot: Rename boot_enc_decrypt to boot_decrypt_key All of boot_enc_ function follow the same pattern where they take encryption context as the first parameter, and the boot_enc_decrypt stands out here as it does not work around the encryption context, but is rather single-part decryption function only used for decrypting of the image encryption key. Signed-off-by: Dominik Ermel (cherry picked from commit 2371c0aa7f058c04d02894d7e4d64bf9c834b69c) --- boot/bootutil/include/bootutil/enc_key.h | 4 +++- boot/bootutil/src/bootutil_misc.c | 2 +- boot/bootutil/src/encrypted.c | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index d8dab9013..8dd7ca8b7 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -48,6 +48,9 @@ struct enc_key_data { extern const struct bootutil_key bootutil_enc_key; struct boot_status; +/* Decrypt random, symmetric encryption key */ +int boot_decrypt_key(const uint8_t *buf, uint8_t *enckey); + int boot_enc_init(struct enc_key_data *enc_state, uint8_t slot); int boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot); int boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, @@ -55,7 +58,6 @@ int boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, int boot_enc_load(struct enc_key_data *enc_state, int image_index, const struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs); -int boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey); bool boot_enc_valid(struct enc_key_data *enc_state, int image_index, const struct flash_area *fap); void boot_encrypt(struct enc_key_data *enc_state, int image_index, diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index 87b863507..e06ec83d6 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -283,7 +283,7 @@ boot_read_enc_key(const struct flash_area *fap, uint8_t slot, struct boot_status } /* Only try to decrypt non-erased TLV metadata */ if (i != BOOT_ENC_TLV_ALIGN_SIZE) { - rc = boot_enc_decrypt(bs->enctlv[slot], bs->enckey[slot]); + rc = boot_decrypt_key(bs->enctlv[slot], bs->enckey[slot]); } } #else diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index 44975cc49..d8e3292ec 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -415,7 +415,7 @@ static int fake_rng(void *p_rng, unsigned char *output, size_t len) * @param enckey An AES-128 or AES-256 key sized buffer to store to plain key. */ int -boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey) +boot_decrypt_key(const uint8_t *buf, uint8_t *enckey) { #if defined(MCUBOOT_ENCRYPT_RSA) bootutil_rsa_context rsa; @@ -660,7 +660,7 @@ boot_enc_load(struct enc_key_data *enc_state, int image_index, return -1; } - return boot_enc_decrypt(buf, bs->enckey[slot]); + return boot_decrypt_key(buf, bs->enckey[slot]); } bool From 8d04aa0c63567d9c7bf6fa2c7205e108b0e8dbde Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 17 Jul 2024 12:11:55 +0000 Subject: [PATCH 072/238] [nrf fromtree] boot: Move encryption context invalidation to boot_enc_drop. The enc_key_data.valid had been set to true when key has been added to the encryption context, but in case when boot_enc_drop was called, on the same context, the flag remained true, even though the context may no longer hold any valid context nor key. The commit moves the enc_key_data invalidation to enc_key_drop. Signed-off-by: Dominik Ermel (cherry picked from commit 335573520dbe64392280fab0e94edc50dc0cb05b) --- boot/bootutil/src/encrypted.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index d8e3292ec..09b9a78df 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -347,6 +347,7 @@ int boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot) { bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr); + enc_state[slot].valid = 0; return 0; } @@ -359,7 +360,6 @@ boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]); if (rc != 0) { boot_enc_drop(enc_state, slot); - enc_state[slot].valid = 0; return -1; } From 852f9af2a37a16b62b95ccc8257e9069e71f2361 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 12 Jul 2024 19:21:40 +0000 Subject: [PATCH 073/238] [nrf fromtree] boot: Change boot_enc_load to take slot number instead of image In all cases where boot_enc_load is called it is known what slot is addressed, so it is better to just pass the slot number instead of making the boot_enc_load figure out slot number from image index and provided flash area object. Signed-off-by: Dominik Ermel (cherry picked from commit 7f9ac97951b989e4e71a8f87dbb7187ec10ffb06) --- boot/boot_serial/src/boot_serial_encryption.c | 7 ++----- boot/bootutil/include/bootutil/enc_key.h | 2 +- boot/bootutil/src/encrypted.c | 9 +-------- boot/bootutil/src/loader.c | 20 +++++++++---------- 4 files changed, 13 insertions(+), 25 deletions(-) diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index 6717826f1..cf9040b30 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -36,7 +36,7 @@ boot_image_validate_encrypted(const struct flash_area *fa_p, memset(&boot_data, 0, sizeof(struct boot_loader_state)); image_index = BOOT_CURR_IMG(state); if(IS_ENCRYPTED(hdr)) { - rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs); + rc = boot_enc_load(BOOT_CURR_ENC(state), 1, hdr, fa_p, bs); if (rc < 0) { FIH_RET(fih_rc); } @@ -218,7 +218,6 @@ decrypt_image_inplace(const struct flash_area *fa_p, size_t sect_size; size_t sect_count; size_t sect; - uint8_t image_index; struct flash_sector sector; memset(&boot_data, 0, sizeof(struct boot_loader_state)); @@ -228,8 +227,6 @@ decrypt_image_inplace(const struct flash_area *fa_p, rc = flash_area_get_sector(fa_p, boot_status_off(fa_p), §or); - image_index = BOOT_CURR_IMG(state); - if(IS_ENCRYPTED(hdr)) { #if 0 //Skip this step?, the image will just not boot if it's not decrypted properly static uint8_t tmpbuf[BOOT_TMPBUF_SZ]; @@ -241,7 +238,7 @@ decrypt_image_inplace(const struct flash_area *fa_p, #endif memset(&boot_data, 0, sizeof(struct boot_loader_state)); /* Load the encryption keys into cache */ - rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs); + rc = boot_enc_load(BOOT_CURR_ENC(state), 0, hdr, fa_p, bs); if (rc < 0) { FIH_RET(fih_rc); } diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index 8dd7ca8b7..8db6e72c8 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -55,7 +55,7 @@ int boot_enc_init(struct enc_key_data *enc_state, uint8_t slot); int boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot); int boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, const struct boot_status *bs); -int boot_enc_load(struct enc_key_data *enc_state, int image_index, +int boot_enc_load(struct enc_key_data *enc_state, int slot, const struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs); bool boot_enc_valid(struct enc_key_data *enc_state, int image_index, diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index 09b9a78df..f3516ac74 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -607,7 +607,7 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey) * Load encryption key. */ int -boot_enc_load(struct enc_key_data *enc_state, int image_index, +boot_enc_load(struct enc_key_data *enc_state, int slot, const struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs) { @@ -619,15 +619,8 @@ boot_enc_load(struct enc_key_data *enc_state, int image_index, #else uint8_t buf[EXPECTED_ENC_LEN]; #endif - uint8_t slot; int rc; - rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fap)); - if (rc < 0) { - return rc; - } - slot = rc; - /* Already loaded... */ if (enc_state[slot].valid) { return 1; diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 4a93b8dbd..c976aa087 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -854,7 +854,6 @@ boot_image_check(struct boot_loader_state *state, struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs) { TARGET_STATIC uint8_t tmpbuf[BOOT_TMPBUF_SZ]; - uint8_t image_index; int rc; FIH_DECLARE(fih_rc, FIH_FAILURE); @@ -865,13 +864,11 @@ boot_image_check(struct boot_loader_state *state, struct image_header *hdr, (void)bs; (void)rc; - image_index = BOOT_CURR_IMG(state); - /* In the case of ram loading the image has already been decrypted as it is * decrypted when copied in ram */ #if defined(MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_RAM_LOAD) - if (MUST_DECRYPT(fap, image_index, hdr)) { - rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap, bs); + if (MUST_DECRYPT(fap, BOOT_CURR_IMG(state), hdr)) { + rc = boot_enc_load(BOOT_CURR_ENC(state), 1, hdr, fap, bs); if (rc < 0) { FIH_RET(fih_rc); } @@ -881,8 +878,9 @@ boot_image_check(struct boot_loader_state *state, struct image_header *hdr, } #endif - FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), image_index, - hdr, fap, tmpbuf, BOOT_TMPBUF_SZ, NULL, 0, NULL); + FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), + BOOT_CURR_IMG(state), hdr, fap, tmpbuf, BOOT_TMPBUF_SZ, + NULL, 0, NULL); FIH_RET(fih_rc); } @@ -1774,7 +1772,7 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) #ifdef MCUBOOT_ENC_IMAGES if (IS_ENCRYPTED(boot_img_hdr(state, BOOT_SECONDARY_SLOT))) { - rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, + rc = boot_enc_load(BOOT_CURR_ENC(state), BOOT_SECONDARY_SLOT, boot_img_hdr(state, BOOT_SECONDARY_SLOT), fap_secondary_slot, bs); @@ -1898,7 +1896,7 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) #ifdef MCUBOOT_ENC_IMAGES if (IS_ENCRYPTED(hdr)) { fap = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); - rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap, bs); + rc = boot_enc_load(BOOT_CURR_ENC(state), 0, hdr, fap, bs); assert(rc >= 0); if (rc == 0) { @@ -1922,7 +1920,7 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); if (IS_ENCRYPTED(hdr)) { fap = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap, bs); + rc = boot_enc_load(BOOT_CURR_ENC(state), 1, hdr, fap, bs); assert(rc >= 0); if (rc == 0) { @@ -3149,7 +3147,7 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, goto done; } - rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap_src, &bs); + rc = boot_enc_load(BOOT_CURR_ENC(state), slot, hdr, fap_src, &bs); if (rc < 0) { goto done; } From c77f4110ceb8fecec61d117027e2fdc763f4ebf4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 18 Jul 2024 16:43:57 +0000 Subject: [PATCH 074/238] [nrf fromtree] boot: Reduce repeating code in boot_decrypt_and_copy_image_to_sram There was not really needed repetition of code in if-else block; common code has been moved out and the block has been reduced. Signed-off-by: Dominik Ermel (cherry picked from commit d09112acf6422c80997a1eea9db7440f25984338) --- boot/bootutil/src/loader.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index c976aa087..591518a77 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -3168,21 +3168,15 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, cur_dst = ram_dst + bytes_copied; blk_sz = chunk_sz; idx = 0; + blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf; if (bytes_copied + chunk_sz > tlv_off) { /* Going over TLV section * Part of the chunk is encrypted payload */ - blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf; blk_sz = tlv_off - (bytes_copied); - boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, - (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, cur_dst); - } else { - /* Image encrypted payload section */ - blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf; - boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, - (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, cur_dst); } + boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, + (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, cur_dst); bytes_copied += chunk_sz; } From a92356827eb2e3b28da47d8007e253896c441c30 Mon Sep 17 00:00:00 2001 From: Fabio Utzig Date: Mon, 15 Jul 2024 20:06:55 -0300 Subject: [PATCH 075/238] [nrf fromtree] Fix style issues Convert tab to spaces; fix opening brace position. Signed-off-by: Fabio Utzig (cherry picked from commit d5e0e89568e6252d713bc5afbd62b1ad6f4de722) --- boot/bootutil/src/loader.c | 3 +-- boot/bootutil/src/swap_move.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 591518a77..e2dd0f08e 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1652,8 +1652,7 @@ boot_copy_region(struct boot_loader_state *state, blk_off = (abs_off - hdr->ih_hdr_size) & 0xf; } - if (blk_sz > 0) - { + if (blk_sz > 0) { tlv_off = BOOT_TLV_OFF(hdr); if (abs_off + chunk_sz > tlv_off) { /* do not decrypt TLVs */ diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 5e6723bb6..4dce64425 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -86,7 +86,7 @@ boot_read_image_header(struct boot_loader_state *state, int slot, off = 0; if (bs && !boot_status_is_reset(bs)) { - boot_find_status(BOOT_CURR_IMG(state), &fap); + boot_find_status(BOOT_CURR_IMG(state), &fap); if (fap == NULL || boot_read_swap_size(fap, &swap_size)) { rc = BOOT_EFLASH; goto done; From 8b0d958ee05c6f05bdf26c50ee2754c092618824 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 17 Jul 2024 14:43:05 +0000 Subject: [PATCH 076/238] [nrf fromtree] boot: Remove image_index from boot_encrypt boot_encrypt required the image_index paired with flash area pointer to be able to figure out which slot it will operate on. Since in most calls the slot is known in advance it can be just passed to the function directly. The commit replaces both parameters with slot number. Signed-off-by: Dominik Ermel (cherry picked from commit 3f11286e2e7e14eb74df1edb278e26371e1e81c9) --- boot/boot_serial/src/boot_serial_encryption.c | 8 ++++---- boot/bootutil/include/bootutil/enc_key.h | 5 ++--- boot/bootutil/src/encrypted.c | 14 +++----------- boot/bootutil/src/image_validate.c | 7 +++++-- boot/bootutil/src/loader.c | 13 ++++++------- 5 files changed, 20 insertions(+), 27 deletions(-) diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index cf9040b30..7d3b47c72 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -125,10 +125,11 @@ decrypt_region_inplace(struct boot_loader_state *state, size_t blk_off; uint16_t idx; uint32_t blk_sz; - uint8_t image_index; - + int slot = flash_area_id_to_multi_image_slot(BOOT_CURR_IMG(state), + flash_area_get_id(fap)); uint8_t buf[sz] __attribute__((aligned)); assert(sz <= sizeof buf); + assert(slot >= 0); bytes_copied = 0; while (bytes_copied < sz) { @@ -143,7 +144,6 @@ decrypt_region_inplace(struct boot_loader_state *state, return BOOT_EFLASH; } - image_index = BOOT_CURR_IMG(state); if (IS_ENCRYPTED(hdr)) { blk_sz = chunk_sz; idx = 0; @@ -171,7 +171,7 @@ decrypt_region_inplace(struct boot_loader_state *state, blk_sz = tlv_off - (off + bytes_copied); } } - boot_encrypt(BOOT_CURR_ENC(state), image_index, flash_area_get_id(fap), + boot_encrypt(BOOT_CURR_ENC(state), slot, (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index 8db6e72c8..a86430937 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -60,9 +60,8 @@ int boot_enc_load(struct enc_key_data *enc_state, int slot, struct boot_status *bs); bool boot_enc_valid(struct enc_key_data *enc_state, int image_index, const struct flash_area *fap); -void boot_encrypt(struct enc_key_data *enc_state, int image_index, - int fa_id, uint32_t off, uint32_t sz, - uint32_t blk_off, uint8_t *buf); +void boot_encrypt(struct enc_key_data *enc_state, int slot, + uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); void boot_enc_zeroize(struct enc_key_data *enc_state); #ifdef __cplusplus diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index f3516ac74..313e018ca 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -673,13 +673,11 @@ boot_enc_valid(struct enc_key_data *enc_state, int image_index, } void -boot_encrypt(struct enc_key_data *enc_state, int image_index, - int fa_id, uint32_t off, uint32_t sz, - uint32_t blk_off, uint8_t *buf) +boot_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, + uint32_t sz, uint32_t blk_off, uint8_t *buf) { struct enc_key_data *enc; uint8_t nonce[16]; - int rc; /* boot_copy_region will call boot_encrypt with sz = 0 when skipping over the TLVs. */ @@ -694,13 +692,7 @@ boot_encrypt(struct enc_key_data *enc_state, int image_index, nonce[14] = (uint8_t)(off >> 8); nonce[15] = (uint8_t)off; - rc = flash_area_id_to_multi_image_slot(image_index, fa_id); - if (rc < 0) { - assert(0); - return; - } - - enc = &enc_state[rc]; + enc = &enc_state[slot]; assert(enc->valid == 1); bootutil_aes_ctr_encrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf); } diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 09b8082ec..851d667af 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -157,10 +157,13 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, #ifdef MCUBOOT_ENC_IMAGES if (MUST_DECRYPT(fap, image_index, hdr)) { /* Only payload is encrypted (area between header and TLVs) */ + int slot = flash_area_id_to_multi_image_slot(image_index, + flash_area_get_id(fap)); + if (off >= hdr_size && off < tlv_off) { blk_off = (off - hdr_size) & 0xf; - boot_encrypt(enc_state, image_index, flash_area_get_id(fap), off - hdr_size, - blk_sz, blk_off, tmp_buf); + boot_encrypt(enc_state, slot, off - hdr_size, + blk_sz, blk_off, tmp_buf); } } #endif diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index e2dd0f08e..102bbe30c 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1574,13 +1574,14 @@ boot_copy_region(struct boot_loader_state *state, uint32_t off; uint32_t tlv_off; size_t blk_off; - int enc_area_id; struct image_header *hdr; uint16_t idx; uint32_t blk_sz; uint8_t image_index; bool encrypted_src; bool encrypted_dst; + /* Assuming the secondary slot is source and needs decryption */ + int source_slot = 1; #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES struct image_header *hdr; @@ -1626,11 +1627,11 @@ boot_copy_region(struct boot_loader_state *state, if (encrypted_dst) { /* Need encryption, metadata from the primary slot */ hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT); - enc_area_id = FLASH_AREA_IMAGE_PRIMARY(image_index); + source_slot = 0; } else { /* Need decryption, metadata from the secondary slot */ hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); - enc_area_id = FLASH_AREA_IMAGE_SECONDARY(image_index); + source_slot = 1; } if (IS_ENCRYPTED(hdr)) { @@ -1662,7 +1663,7 @@ boot_copy_region(struct boot_loader_state *state, blk_sz = tlv_off - abs_off; } } - boot_encrypt(BOOT_CURR_ENC(state), image_index, enc_area_id, + boot_encrypt(BOOT_CURR_ENC(state), source_slot, (abs_off + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } @@ -3125,13 +3126,11 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, uint32_t chunk_sz; uint32_t max_sz = 1024; uint16_t idx; - uint8_t image_index; uint8_t * cur_dst; int area_id; int rc; uint8_t * ram_dst = (void *)(IMAGE_RAM_BASE + img_dst); - image_index = BOOT_CURR_IMG(state); area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot); rc = flash_area_open(area_id, &fap_src); if (rc != 0){ @@ -3173,7 +3172,7 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, * Part of the chunk is encrypted payload */ blk_sz = tlv_off - (bytes_copied); } - boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, + boot_encrypt(BOOT_CURR_ENC(state), slot, (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, cur_dst); From c04fb82970f8fa15e0e6359865214363542e5f18 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 18 Jul 2024 11:40:53 +0000 Subject: [PATCH 077/238] [nrf fromtree] boot: Simplify copy loop in boot_copy_region Move checking of conditions, which remain the same for the whole loop run, outside of the loop. Signed-off-by: Dominik Ermel (cherry picked from commit 6fe259b1b6780ba98362a9ced88f24a8325729ad) --- boot/bootutil/src/loader.c | 110 ++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 49 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 102bbe30c..42a370a79 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1571,17 +1571,26 @@ boot_copy_region(struct boot_loader_state *state, int chunk_sz; int rc; #ifdef MCUBOOT_ENC_IMAGES - uint32_t off; + uint32_t off = off_dst; uint32_t tlv_off; size_t blk_off; struct image_header *hdr; uint16_t idx; uint32_t blk_sz; - uint8_t image_index; + uint8_t image_index = BOOT_CURR_IMG(state); bool encrypted_src; bool encrypted_dst; - /* Assuming the secondary slot is source and needs decryption */ + /* Assuming the secondary slot is source; note that 0 here not only + * means that primary slot is source, but also that there will be + * encryption happening, if it is 1 then there is decryption from + * secondary slot. + */ int source_slot = 1; + /* In case of encryption enabled, we may have to do more work than + * just copy bytes */ + bool only_copy = false; +#else + (void)state; #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES struct image_header *hdr; @@ -1589,8 +1598,26 @@ boot_copy_region(struct boot_loader_state *state, TARGET_STATIC uint8_t buf[BUF_SZ] __attribute__((aligned(4))); -#if !defined(MCUBOOT_ENC_IMAGES) - (void)state; +#ifdef MCUBOOT_ENC_IMAGES + encrypted_src = (flash_area_get_id(fap_src) != FLASH_AREA_IMAGE_PRIMARY(image_index)); + encrypted_dst = (flash_area_get_id(fap_dst) != FLASH_AREA_IMAGE_PRIMARY(image_index)); + + if (encrypted_src != encrypted_dst) { + if (encrypted_dst) { + /* Need encryption, metadata from the primary slot */ + hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT); + source_slot = 0; + } else { + /* Need decryption, metadata from the secondary slot */ + hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + source_slot = 1; + } + } else { + /* In case when source and targe is the same area, this means that we + * only have to copy bytes, no encryption or decryption. + */ + only_copy = true; + } #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES @@ -1617,56 +1644,41 @@ boot_copy_region(struct boot_loader_state *state, } #ifdef MCUBOOT_ENC_IMAGES - image_index = BOOT_CURR_IMG(state); - encrypted_src = (flash_area_get_id(fap_src) != FLASH_AREA_IMAGE_PRIMARY(image_index)); - encrypted_dst = (flash_area_get_id(fap_dst) != FLASH_AREA_IMAGE_PRIMARY(image_index)); - - if (encrypted_src != encrypted_dst) { - off = off_dst; - - if (encrypted_dst) { - /* Need encryption, metadata from the primary slot */ - hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT); - source_slot = 0; + /* If only copy, then does not matter if header indicates need for + * encryptio/decryptio, we just copy data. */ + if (!only_copy && IS_ENCRYPTED(hdr)) { + uint32_t abs_off = off + bytes_copied; + if (abs_off < hdr->ih_hdr_size) { + /* do not decrypt header */ + if (abs_off + chunk_sz > hdr->ih_hdr_size) { + /* The lower part of the chunk contains header data */ + blk_off = 0; + blk_sz = chunk_sz - (hdr->ih_hdr_size - abs_off); + idx = hdr->ih_hdr_size - abs_off; + } else { + /* The chunk contains exclusively header data */ + blk_sz = 0; /* nothing to decrypt */ + } } else { - /* Need decryption, metadata from the secondary slot */ - hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); - source_slot = 1; + idx = 0; + blk_sz = chunk_sz; + blk_off = (abs_off - hdr->ih_hdr_size) & 0xf; } - if (IS_ENCRYPTED(hdr)) { - uint32_t abs_off = off + bytes_copied; - if (abs_off < hdr->ih_hdr_size) { - /* do not decrypt header */ - if (abs_off + chunk_sz > hdr->ih_hdr_size) { - /* The lower part of the chunk contains header data */ - blk_off = 0; - blk_sz = chunk_sz - (hdr->ih_hdr_size - abs_off); - idx = hdr->ih_hdr_size - abs_off; + if (blk_sz > 0) + { + tlv_off = BOOT_TLV_OFF(hdr); + if (abs_off + chunk_sz > tlv_off) { + /* do not decrypt TLVs */ + if (abs_off >= tlv_off) { + blk_sz = 0; } else { - /* The chunk contains exclusively header data */ - blk_sz = 0; /* nothing to decrypt */ - } - } else { - idx = 0; - blk_sz = chunk_sz; - blk_off = (abs_off - hdr->ih_hdr_size) & 0xf; - } - - if (blk_sz > 0) { - tlv_off = BOOT_TLV_OFF(hdr); - if (abs_off + chunk_sz > tlv_off) { - /* do not decrypt TLVs */ - if (abs_off >= tlv_off) { - blk_sz = 0; - } else { - blk_sz = tlv_off - abs_off; - } + blk_sz = tlv_off - abs_off; } - boot_encrypt(BOOT_CURR_ENC(state), source_slot, - (abs_off + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, &buf[idx]); } + boot_encrypt(BOOT_CURR_ENC(state), source_slot, + (abs_off + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, &buf[idx]); } } #endif From 3d1c64b983066bd0a3a3319114903a8063ca8374 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 12 Jul 2024 19:53:24 +0000 Subject: [PATCH 078/238] [nrf fromtree] boot: Make boot_enc_valid take slot instead of image index There is no point for boot_enc_valid to take image index and flash area and use these to figure out slot number. Signed-off-by: Dominik Ermel (cherry picked from commit 956311d2d5e5b73c9cbb8d7366f994fd31c4e986) --- boot/bootutil/include/bootutil/enc_key.h | 3 +-- boot/bootutil/src/encrypted.c | 14 ++------------ boot/bootutil/src/image_validate.c | 2 +- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index a86430937..ceb7c21d9 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -58,8 +58,7 @@ int boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, int boot_enc_load(struct enc_key_data *enc_state, int slot, const struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs); -bool boot_enc_valid(struct enc_key_data *enc_state, int image_index, - const struct flash_area *fap); +bool boot_enc_valid(struct enc_key_data *enc_state, int slot); void boot_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); void boot_enc_zeroize(struct enc_key_data *enc_state); diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index 313e018ca..e8f4a40cd 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -657,19 +657,9 @@ boot_enc_load(struct enc_key_data *enc_state, int slot, } bool -boot_enc_valid(struct enc_key_data *enc_state, int image_index, - const struct flash_area *fap) +boot_enc_valid(struct enc_key_data *enc_state, int slot) { - int rc; - - rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fap)); - if (rc < 0) { - /* can't get proper slot number - skip encryption, */ - /* postpone the error for a upper layer */ - return false; - } - - return enc_state[rc].valid; + return enc_state[slot].valid; } void diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 851d667af..4db434d6e 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -105,7 +105,7 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, #ifdef MCUBOOT_ENC_IMAGES /* Encrypted images only exist in the secondary slot */ if (MUST_DECRYPT(fap, image_index, hdr) && - !boot_enc_valid(enc_state, image_index, fap)) { + !boot_enc_valid(enc_state, 1)) { return -1; } #endif From b1b4ec39820c1fedd2bb203210425be61071ff83 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 18 Jul 2024 17:47:43 +0000 Subject: [PATCH 079/238] [nrf fromlist] boot: Replace boot_encrypt by boot_enc_encrypt and boot_enc_decrypt To be able to implement encryption with API that requires different calls for encryption and encryption, the boot_encrypt needs to be replaced with encryption/decryption specific functions. Upstream PR: https://github.com/mcu-tools/mcuboot/pull/2017 Signed-off-by: Dominik Ermel --- boot/boot_serial/src/boot_serial_encryption.c | 2 +- boot/bootutil/include/bootutil/enc_key.h | 4 ++- boot/bootutil/src/encrypted.c | 31 ++++++++++++++++--- boot/bootutil/src/image_validate.c | 4 +-- boot/bootutil/src/loader.c | 19 +++++++----- 5 files changed, 44 insertions(+), 16 deletions(-) diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index 7d3b47c72..c4bd7d87b 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -171,7 +171,7 @@ decrypt_region_inplace(struct boot_loader_state *state, blk_sz = tlv_off - (off + bytes_copied); } } - boot_encrypt(BOOT_CURR_ENC(state), slot, + boot_enc_decrypt(BOOT_CURR_ENC(state), slot, (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index ceb7c21d9..966f2d6a7 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -59,7 +59,9 @@ int boot_enc_load(struct enc_key_data *enc_state, int slot, const struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs); bool boot_enc_valid(struct enc_key_data *enc_state, int slot); -void boot_encrypt(struct enc_key_data *enc_state, int slot, +void boot_enc_encrypt(struct enc_key_data *enc_state, int slot, + uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); +void boot_enc_decrypt(struct enc_key_data *enc_state, int slot, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); void boot_enc_zeroize(struct enc_key_data *enc_state); diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index e8f4a40cd..b48f859f6 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -663,14 +663,13 @@ boot_enc_valid(struct enc_key_data *enc_state, int slot) } void -boot_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, +boot_enc_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf) { - struct enc_key_data *enc; + struct enc_key_data *enc = &enc_state[slot]; uint8_t nonce[16]; - /* boot_copy_region will call boot_encrypt with sz = 0 when skipping over - the TLVs. */ + /* Nothing to do with size == 0 */ if (sz == 0) { return; } @@ -682,11 +681,33 @@ boot_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, nonce[14] = (uint8_t)(off >> 8); nonce[15] = (uint8_t)off; - enc = &enc_state[slot]; assert(enc->valid == 1); bootutil_aes_ctr_encrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf); } +void +boot_enc_decrypt(struct enc_key_data *enc_state, int slot, uint32_t off, + uint32_t sz, uint32_t blk_off, uint8_t *buf) +{ + struct enc_key_data *enc = &enc_state[slot]; + uint8_t nonce[16]; + + /* Nothing to do with size == 0 */ + if (sz == 0) { + return; + } + + memset(nonce, 0, 12); + off >>= 4; + nonce[12] = (uint8_t)(off >> 24); + nonce[13] = (uint8_t)(off >> 16); + nonce[14] = (uint8_t)(off >> 8); + nonce[15] = (uint8_t)off; + + assert(enc->valid == 1); + bootutil_aes_ctr_decrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf); +} + /** * Clears encrypted state after use. */ diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 4db434d6e..a6155f7b0 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -162,8 +162,8 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, if (off >= hdr_size && off < tlv_off) { blk_off = (off - hdr_size) & 0xf; - boot_encrypt(enc_state, slot, off - hdr_size, - blk_sz, blk_off, tmp_buf); + boot_enc_decrypt(enc_state, slot, off - hdr_size, + blk_sz, blk_off, tmp_buf); } } #endif diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 42a370a79..9f2843a0d 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1676,9 +1676,15 @@ boot_copy_region(struct boot_loader_state *state, blk_sz = tlv_off - abs_off; } } - boot_encrypt(BOOT_CURR_ENC(state), source_slot, - (abs_off + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, &buf[idx]); + if (source_slot == 0) { + boot_enc_encrypt(BOOT_CURR_ENC(state), source_slot, + (abs_off + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, &buf[idx]); + } else { + boot_enc_decrypt(BOOT_CURR_ENC(state), source_slot, + (abs_off + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, &buf[idx]); + } } } #endif @@ -3184,10 +3190,9 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, * Part of the chunk is encrypted payload */ blk_sz = tlv_off - (bytes_copied); } - boot_encrypt(BOOT_CURR_ENC(state), slot, - (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, cur_dst); - + boot_enc_decrypt(BOOT_CURR_ENC(state), slot, + (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, cur_dst); bytes_copied += chunk_sz; } rc = 0; From be3637e0404f3e3b81eee75903f70532e3c6914f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 24 Jul 2024 17:00:04 +0000 Subject: [PATCH 080/238] [nrf noup] PSA configuration required changes Set of changes to Kconfig, CMakeLists.txt and some of headers that are required for the PSA support to compile. Signed-off-by: Dominik Ermel --- boot/bootutil/zephyr/CMakeLists.txt | 14 +++-- boot/zephyr/CMakeLists.txt | 39 ++++++++---- boot/zephyr/Kconfig | 72 ++++++++++++++++++++++- boot/zephyr/include/mcuboot-mbedtls-cfg.h | 2 +- 4 files changed, 111 insertions(+), 16 deletions(-) diff --git a/boot/bootutil/zephyr/CMakeLists.txt b/boot/bootutil/zephyr/CMakeLists.txt index 72a6a8638..d5364d025 100644 --- a/boot/bootutil/zephyr/CMakeLists.txt +++ b/boot/bootutil/zephyr/CMakeLists.txt @@ -29,12 +29,18 @@ zephyr_library_link_libraries(MCUBOOT_BOOTUTIL) target_link_libraries(MCUBOOT_BOOTUTIL INTERFACE zephyr_interface) if(CONFIG_BOOT_USE_TINYCRYPT) -target_include_directories(MCUBOOT_BOOTUTIL INTERFACE - ../../../ext/tinycrypt/lib/include -) + target_include_directories(MCUBOOT_BOOTUTIL INTERFACE + ../../../ext/tinycrypt/lib/include + ) +endif() + +if(CONFIG_BOOT_USE_PSA_CRYPTO) + target_include_directories(MCUBOOT_BOOTUTIL INTERFACE + ${ZEPHYR_MBEDTLS_MODULE_DIR}/include + ) endif() -if(CONFIG_BOOT_USE_MBEDTLS) +if(CONFIG_BOOT_USE_MBEDTLS OR CONFIG_BOOT_USE_PSA_CRYPTO AND NOT CONFIG_PSA_CORE_OBERON) zephyr_link_libraries(mbedTLS) endif() endif() diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index c26633d11..8a2c97ead 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -51,6 +51,12 @@ if(EXISTS targets/${BOARD}.h) zephyr_library_compile_definitions(MCUBOOT_TARGET_CONFIG="${BOARD}.h") endif() +if(DEFINED CONFIG_MBEDTLS) + zephyr_library_include_directories( + ${ZEPHYR_MBEDTLS_MODULE_DIR}/include + ) +endif() + # Zephyr port-specific sources. zephyr_library_sources( main.c @@ -102,6 +108,10 @@ zephyr_library_sources( ${BOOT_DIR}/bootutil/src/fault_injection_hardening.c ) +if(DEFINED CONFIG_BOOT_ENCRYPT_X25519) + zephyr_library_sources(${BOOT_DIR}/bootutil/src/encrypted_psa.c) +endif() + if(DEFINED CONFIG_MEASURED_BOOT OR DEFINED CONFIG_BOOT_SHARE_DATA) zephyr_library_sources( ${BOOT_DIR}/bootutil/src/boot_record.c @@ -230,19 +240,28 @@ elseif(CONFIG_BOOT_SIGNATURE_TYPE_ED25519 OR CONFIG_BOOT_ENCRYPT_X25519) ${FIAT_DIR}/include/ ) - zephyr_library_sources( - ${FIAT_DIR}/src/curve25519.c - ) + if(NOT CONFIG_BOOT_ED25519_PSA) + zephyr_library_sources( + ${FIAT_DIR}/src/curve25519.c + ) + else() + zephyr_library_sources( + ${MBEDTLS_ASN1_DIR}/src/asn1parse.c + ${BOOT_DIR}/bootutil/src/ed25519_psa.c + ) + endif() endif() -if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519) - zephyr_library_sources( - ${TINYCRYPT_DIR}/source/aes_encrypt.c - ${TINYCRYPT_DIR}/source/aes_decrypt.c - ${TINYCRYPT_DIR}/source/ctr_mode.c - ${TINYCRYPT_DIR}/source/hmac.c - ${TINYCRYPT_DIR}/source/ecc_dh.c +if(NOT CONFIG_BOOT_ED25519_PSA) + if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519) + zephyr_library_sources( + ${TINYCRYPT_DIR}/source/aes_encrypt.c + ${TINYCRYPT_DIR}/source/aes_decrypt.c + ${TINYCRYPT_DIR}/source/ctr_mode.c + ${TINYCRYPT_DIR}/source/hmac.c + ${TINYCRYPT_DIR}/source/ecc_dh.c ) + endif() endif() if(CONFIG_BOOT_ENCRYPT_EC256) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 8b35ab18c..264c08241 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -29,7 +29,9 @@ config BOOT_USE_MBEDTLS config BOOT_USE_PSA_CRYPTO bool - # Hidden option + default y if NRF_SECURITY + # This is counter intuitive but that is how PSA heap is enabled. + select MBEDTLS_ENABLE_HEAP help Hidden option set if using PSA crypt for cryptography functionality @@ -66,6 +68,58 @@ config NRF_CC310_BL bool default n +if BOOT_USE_PSA_CRYPTO + +config BOOT_PSA_IMG_HASH_ALG_SHA256_DEPENDENCIES + bool + default y if BOOT_IMG_HASH_ALG_SHA256 + select PSA_WANT_ALG_SHA_256 + help + Dependencies for hashing with SHA256 + +config BOOT_ED25519_PSA_DEPENDENCIES + bool + select PSA_WANT_ALG_SHA_256 + select PSA_WANT_ALG_SHA_512 + select PSA_WANT_ALG_PURE_EDDSA + select PSA_WANT_ECC_TWISTED_EDWARDS_255 + select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT + help + Dependencies for ed25519 signature + +if BOOT_ENCRYPT_IMAGE + +config BOOT_X25519_PSA_DEPENDENCIES + bool + select PSA_WANT_ALG_ECDH + select PSA_WANT_ALG_HMAC + select PSA_WANT_ALG_HKDF + select PSA_WANT_ALG_CTR + select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT + select PSA_WANT_KEY_TYPE_DERIVE + select PSA_WANT_KEY_TYPE_AES + select PSA_WANT_ECC_MONTGOMERY_255 + help + Dependencies for x25519 shared-random key encryption and AES + encryption. The PSA_WANT_ALG_CTR and PSA_WANT_KEY_TYPE_AES + enable Counter based block cipher and AES key, and algorithm support, + to use with it; the others are used for shared key decryption + and derivation. + +endif # BOOT_ENCRYPT_IMAGE + +if MBEDTLS_ENABLE_HEAP + +config MBEDTLS_HEAP_SIZE + default 2048 if BOOT_USE_PSA_CRYPTO + help + The PSA internals need to be able to allocate memory for operation + and it uses mbedTLS heap for that. + +endif # MBEDTLS_ENABLE_HEAP + +endif # BOOT_USE_PSA_CRYPTO + menu "MCUBoot settings" config SINGLE_APPLICATION_SLOT @@ -124,6 +178,7 @@ endchoice # BOOT_IMG_HASH_ALG choice BOOT_SIGNATURE_TYPE prompt "Signature type" + default BOOT_SIGNATURE_TYPE_ED25519 if BOARD_NRF54L15PDK_NRF54L15_CPUAPP default BOOT_SIGNATURE_TYPE_RSA config BOOT_SIGNATURE_TYPE_NONE @@ -178,13 +233,24 @@ if BOOT_SIGNATURE_TYPE_ED25519 choice BOOT_ED25519_IMPLEMENTATION prompt "Ecdsa implementation" default BOOT_ED25519_TINYCRYPT + config BOOT_ED25519_TINYCRYPT bool "Use tinycrypt" select BOOT_USE_TINYCRYPT + depends on !NRF_SECURITY + config BOOT_ED25519_MBEDTLS bool "Use mbedTLS" select BOOT_USE_MBEDTLS select MBEDTLS + depends on !NRF_SECURITY + +config BOOT_ED25519_PSA + bool "Use PSA crypto" + select BOOT_USE_PSA_CRYPTO + select BOOT_ED25519_PSA_DEPENDENCIES + select BOOT_X25519_PSA_DEPENDENCIES if BOOT_ENCRYPT_IMAGE + endchoice endif @@ -223,9 +289,13 @@ config MCUBOOT_CLEANUP_ARM_CORE start-up code which can cause a module fault and potentially make the module irrecoverable. +if MBEDTLS + config MBEDTLS_CFG_FILE default "mcuboot-mbedtls-cfg.h" +endif + config BOOT_HW_KEY bool "Use HW key for image verification" default n diff --git a/boot/zephyr/include/mcuboot-mbedtls-cfg.h b/boot/zephyr/include/mcuboot-mbedtls-cfg.h index 2bab537d7..a46fbb09f 100644 --- a/boot/zephyr/include/mcuboot-mbedtls-cfg.h +++ b/boot/zephyr/include/mcuboot-mbedtls-cfg.h @@ -23,7 +23,7 @@ #if defined(CONFIG_BOOT_SIGNATURE_TYPE_RSA) || defined(CONFIG_BOOT_ENCRYPT_RSA) #include "config-rsa.h" -#elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) || \ +#elif defined(CONFIG_BOOT_USE_PSA_CRYPTO) || defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) || \ defined(CONFIG_BOOT_ENCRYPT_EC256) || \ (defined(CONFIG_BOOT_ENCRYPT_X25519) && !defined(CONFIG_BOOT_SIGNATURE_TYPE_ED25519)) #include "config-asn1.h" From 5f95fecfa27e5b9924a91c69bca023e605fe751e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 29 May 2024 17:46:17 +0000 Subject: [PATCH 081/238] [nrf noup] PSA implementation of x25519 and ed25519 verification The commit provides implementation of image verification with ed25519 and encryption/decryption support where random key is encrypted using x25519. Signed-off-by: Dominik Ermel --- .../include/bootutil/crypto/aes_ctr.h | 38 +- boot/bootutil/src/ed25519_psa.c | 71 +++ boot/bootutil/src/encrypted.c | 114 ++--- boot/bootutil/src/encrypted_psa.c | 453 ++++++++++++++++++ boot/bootutil/src/image_ed25519.c | 18 +- 5 files changed, 634 insertions(+), 60 deletions(-) create mode 100644 boot/bootutil/src/ed25519_psa.c create mode 100644 boot/bootutil/src/encrypted_psa.c diff --git a/boot/bootutil/include/bootutil/crypto/aes_ctr.h b/boot/bootutil/include/bootutil/crypto/aes_ctr.h index e69b0372f..fd2416176 100644 --- a/boot/bootutil/include/bootutil/crypto/aes_ctr.h +++ b/boot/bootutil/include/bootutil/crypto/aes_ctr.h @@ -15,8 +15,8 @@ #include "mcuboot_config/mcuboot_config.h" #if (defined(MCUBOOT_USE_MBED_TLS) + \ - defined(MCUBOOT_USE_TINYCRYPT)) != 1 - #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT" + defined(MCUBOOT_USE_TINYCRYPT) + defined(MCUBOOT_USE_PSA_CRYPTO)) != 1 + #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT or PSA" #endif #if defined(MCUBOOT_USE_MBED_TLS) @@ -38,12 +38,46 @@ #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE TC_AES_BLOCK_SIZE #endif /* MCUBOOT_USE_TINYCRYPT */ + +#if defined(MCUBOOT_USE_PSA_CRYPTO) + #include + #include "bootutil/enc_key_public.h" + #define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE BOOT_ENC_KEY_SIZE + #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16) +#endif + #include #ifdef __cplusplus extern "C" { #endif +#if defined(MCUBOOT_USE_PSA_CRYPTO) +typedef struct { + /* Fixme: This should not be, here, psa_key_id should be passed */ + uint8_t key[BOOT_ENC_KEY_SIZE]; +} bootutil_aes_ctr_context; + +void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx); + +static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx) +{ + memset(ctx, 0, sizeof(ctx)); +} + +static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k) +{ + memcpy(ctx->key, k, sizeof(ctx->key)); + + return 0; +} + +int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, + const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c); +int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, + const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m); +#endif + #if defined(MCUBOOT_USE_MBED_TLS) typedef mbedtls_aes_context bootutil_aes_ctr_context; static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx) diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c new file mode 100644 index 000000000..3d7274307 --- /dev/null +++ b/boot/bootutil/src/ed25519_psa.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include +#include + +#include +#include "bootutil/bootutil_log.h" + +#include +#include + +BOOT_LOG_MODULE_DECLARE(ed25519_psa); + +#define SHA512_DIGEST_LENGTH 64 +#define EDDSA_KEY_LENGTH 32 +#define EDDSA_SIGNAGURE_LENGTH 64 + +int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], + const uint8_t public_key[EDDSA_KEY_LENGTH]) +{ + /* Set to any error */ + psa_status_t status = PSA_ERROR_BAD_STATE; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t kid; + int ret = 0; /* Fail by default */ + + /* Initialize PSA Crypto */ + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + BOOT_LOG_ERR("PSA crypto init failed %d\n", status); + return 0; + } + + status = PSA_ERROR_BAD_STATE; + + psa_set_key_type(&key_attr, + PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS)); + psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&key_attr, PSA_ALG_PURE_EDDSA); + + status = psa_import_key(&key_attr, public_key, EDDSA_KEY_LENGTH, &kid); + if (status != PSA_SUCCESS) { + BOOT_LOG_ERR("ED25519 key import failed %d", status); + return 0; + } + + status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, message_len, + signature, EDDSA_SIGNAGURE_LENGTH); + if (status != PSA_SUCCESS) { + BOOT_LOG_ERR("ED25519 signature verification failed %d", status); + ret = 0; + /* Pass through to destroy key */ + } else { + ret = 1; + /* Pass through to destroy key */ + } + + status = psa_destroy_key(kid); + + if (status != PSA_SUCCESS) { + /* Just for logging */ + BOOT_LOG_WRN("Failed to destroy key %d", status); + } + + return ret; +} diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index b48f859f6..e794fe66c 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -25,6 +25,7 @@ #include "bootutil/crypto/ecdh_p256.h" #endif +#if !defined(MCUBOOT_USE_PSA_CRYPTO) #if defined(MCUBOOT_ENCRYPT_X25519) #include "bootutil/crypto/ecdh_x25519.h" #endif @@ -35,6 +36,7 @@ #include "mbedtls/oid.h" #include "mbedtls/asn1.h" #endif +#endif #include "bootutil/image.h" #include "bootutil/enc_key.h" @@ -43,6 +45,30 @@ #include "bootutil_priv.h" +#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE + +#if defined(MCUBOOT_ENCRYPT_RSA) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048 +#elif defined(MCUBOOT_ENCRYPT_KW) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW +#elif defined(MCUBOOT_ENCRYPT_EC256) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256 +# define EC_PUBK_INDEX (0) +# define EC_TAG_INDEX (65) +# define EC_CIPHERKEY_INDEX (65 + 32) +_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, + "Please fix ECIES-P256 component indexes"); +#elif defined(MCUBOOT_ENCRYPT_X25519) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519 +# define EC_PUBK_INDEX (0) +# define EC_TAG_INDEX (32) +# define EC_CIPHERKEY_INDEX (32 + 32) +_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, + "Please fix ECIES-X25519 component indexes"); +#endif + +/* NOUP Fixme: */ +#if !defined(CONFIG_BOOT_ED25519_PSA) #if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519) #if defined(_compare) static inline int bootutil_constant_time_compare(const uint8_t *a, const uint8_t *b, size_t size) @@ -336,60 +362,6 @@ hkdf(uint8_t *ikm, uint16_t ikm_len, uint8_t *info, uint16_t info_len, } #endif -int -boot_enc_init(struct enc_key_data *enc_state, uint8_t slot) -{ - bootutil_aes_ctr_init(&enc_state[slot].aes_ctr); - return 0; -} - -int -boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot) -{ - bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr); - enc_state[slot].valid = 0; - return 0; -} - -int -boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, - const struct boot_status *bs) -{ - int rc; - - rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]); - if (rc != 0) { - boot_enc_drop(enc_state, slot); - return -1; - } - - enc_state[slot].valid = 1; - - return 0; -} - -#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE - -#if defined(MCUBOOT_ENCRYPT_RSA) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048 -#elif defined(MCUBOOT_ENCRYPT_KW) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW -#elif defined(MCUBOOT_ENCRYPT_EC256) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256 -# define EC_PUBK_INDEX (0) -# define EC_TAG_INDEX (65) -# define EC_CIPHERKEY_INDEX (65 + 32) -_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, - "Please fix ECIES-P256 component indexes"); -#elif defined(MCUBOOT_ENCRYPT_X25519) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519 -# define EC_PUBK_INDEX (0) -# define EC_TAG_INDEX (32) -# define EC_CIPHERKEY_INDEX (32 + 32) -_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, - "Please fix ECIES-X25519 component indexes"); -#endif - #if ( (defined(MCUBOOT_ENCRYPT_RSA) && defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_PSA_CRYPTO)) || \ (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS)) ) #if MBEDTLS_VERSION_NUMBER >= 0x03000000 @@ -602,6 +574,7 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey) return rc; } +#endif /* CONFIG_BOOT_ED25519_PSA */ /* * Load encryption key. @@ -656,6 +629,39 @@ boot_enc_load(struct enc_key_data *enc_state, int slot, return boot_decrypt_key(buf, bs->enckey[slot]); } +int +boot_enc_init(struct enc_key_data *enc_state, uint8_t slot) +{ + bootutil_aes_ctr_init(&enc_state[slot].aes_ctr); + return 0; +} + +int +boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot) +{ + bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr); + enc_state[slot].valid = 0; + return 0; +} + +int +boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, + const struct boot_status *bs) +{ + int rc; + + rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]); + if (rc != 0) { + boot_enc_drop(enc_state, slot); + return -1; + } + + enc_state[slot].valid = 1; + + return 0; +} + + bool boot_enc_valid(struct enc_key_data *enc_state, int slot) { diff --git a/boot/bootutil/src/encrypted_psa.c b/boot/bootutil/src/encrypted_psa.c new file mode 100644 index 000000000..927ce2d6b --- /dev/null +++ b/boot/bootutil/src/encrypted_psa.c @@ -0,0 +1,453 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "mcuboot_config/mcuboot_config.h" + +#include +#include +#include + +/* We are not really using the MBEDTLS but need the ASN.1 parsing functions */ +#define MBEDTLS_ASN1_PARSE_C + +#include "bootutil/crypto/sha.h" +#include "mbedtls/oid.h" +#include "mbedtls/asn1.h" + +#include "bootutil/image.h" +#include "bootutil/enc_key.h" +#include "bootutil/sign_key.h" +#include "bootutil/crypto/common.h" + +#include "bootutil_priv.h" +#include "bootutil/bootutil_log.h" + +BOOT_LOG_MODULE_DECLARE(mcuboot_psa_enc); + +#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE +#define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519 +#define EC_PUBK_INDEX (0) +#define EC_TAG_INDEX (32) +#define EC_CIPHERKEY_INDEX (32 + 32) +_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, + "Please fix ECIES-X25519 component indexes"); + +#define X25519_OID "\x6e" +static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG \ + MBEDTLS_OID_ORG_GOV X25519_OID; + +#define SHARED_KEY_LEN 32 +#define PRIV_KEY_LEN 32 + +/* Fixme: This duplicates code from encrypted.c and depends on mbedtls */ +static int +parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key) +{ + size_t len; + int version; + mbedtls_asn1_buf alg; + mbedtls_asn1_buf param; + + if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE) != 0) { + return -1; + } + + if (*p + len != end) { + return -2; + } + + version = 0; + if (mbedtls_asn1_get_int(p, end, &version) || version != 0) { + return -3; + } + + if (mbedtls_asn1_get_alg(p, end, &alg, ¶m) != 0) { + return -4; + } + + if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || + memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { + return -5; + } + + if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) { + return -6; + } + + if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) { + return -7; + } + + if (len != PRIV_KEY_LEN) { + return -8; + } + + memcpy(private_key, *p, PRIV_KEY_LEN); + return 0; +} + +void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx) +{ + psa_status_t psa_ret = psa_crypto_init(); + + (void)ctx; + + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES init PSA crypto init failed %d", psa_ret); + assert(0); + } +} + +#if defined(MCUBOOT_ENC_IMAGES) +/* + * Decrypt an encryption key TLV. + * + * @param buf An encryption TLV read from flash (build time fixed length) + * @param enckey An AES-128 or AES-256 key sized buffer to store to plain key. + */ +int +boot_decrypt_key(const uint8_t *buf, uint8_t *enckey) +{ + uint8_t derived_key[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE]; + uint8_t *cp; + uint8_t *cpend; + uint8_t private_key[PRIV_KEY_LEN]; + size_t len; + psa_status_t psa_ret = PSA_ERROR_BAD_STATE; + psa_status_t psa_cleanup_ret = PSA_ERROR_BAD_STATE; + psa_key_id_t kid; + psa_key_attributes_t kattr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_derivation_operation_t key_do = PSA_KEY_DERIVATION_OPERATION_INIT; + psa_algorithm_t key_do_alg; + int rc = -1; + + cp = (uint8_t *)bootutil_enc_key.key; + cpend = cp + *bootutil_enc_key.len; + + /* The psa_cipher_decrypt needs initialization vector of proper length at + * the beginning of the input buffer. + */ + uint8_t iv_and_key[PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR) + + BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE]; + + psa_ret = psa_crypto_init(); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES crypto init failed %d", psa_ret); + return -1; + } + + /* + * Load the stored X25519 decryption private key + */ + rc = parse_x25519_enckey(&cp, cpend, private_key); + if (rc) { + return rc; + } + + psa_set_key_type(&kattr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY)); + psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&kattr, PSA_ALG_ECDH); + + psa_ret = psa_import_key(&kattr, private_key, sizeof(private_key), &kid); + memset(private_key, 0, sizeof(private_key)); + psa_reset_key_attributes(&kattr); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("Built-in key import failed %d", psa_ret); + return -1; + } + + key_do_alg = PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)); + + psa_ret = psa_key_derivation_setup(&key_do, key_do_alg); + if (psa_ret != PSA_SUCCESS) { + psa_cleanup_ret = psa_destroy_key(kid); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("Built-in key destruction failed %d", psa_cleanup_ret); + } + BOOT_LOG_ERR("Key derivation setup failed %d", psa_ret); + return -1; + } + + /* Note: PSA 1.1.2 does not have psa_key_agreement that would be useful here + * as it could just add the derived key to the storage and return key id. + * Instead, we have to use the code below to generate derived key and put it + * into storage, to obtain the key id we can then use with psa_mac_* functions. + */ + psa_ret = psa_key_derivation_key_agreement(&key_do, PSA_KEY_DERIVATION_INPUT_SECRET, + kid, &buf[EC_PUBK_INDEX], + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE); + psa_cleanup_ret = psa_destroy_key(kid); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("Built-in key destruction failed %d", psa_cleanup_ret); + } + if (psa_ret != PSA_SUCCESS) { + psa_cleanup_ret = psa_key_derivation_abort(&key_do); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("Key derivation abort failed %d", psa_ret); + } + + BOOT_LOG_ERR("Key derivation failed %d", psa_ret); + return -1; + } + + /* Only info, no salt */ + psa_ret = psa_key_derivation_input_bytes(&key_do, PSA_KEY_DERIVATION_INPUT_INFO, + "MCUBoot_ECIES_v1", 16); + if (psa_ret != PSA_SUCCESS) { + psa_cleanup_ret = psa_key_derivation_abort(&key_do); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("Key derivation abort failed %d", psa_ret); + } + BOOT_LOG_ERR("Key derivation failed %d", psa_ret); + return -1; + } + + len = BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE; + psa_ret = psa_key_derivation_output_bytes(&key_do, derived_key, len); + psa_cleanup_ret = psa_key_derivation_abort(&key_do); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("Key derivation cleanup failed %d", psa_ret); + } + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("Key derivation failed %d", psa_ret); + return -1; + } + + /* The derived key consists of BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE bytes + * followed by BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE bytes. Both parts will + * be imported at the point where needed and discarded immediately after. + */ + psa_set_key_type(&kattr, PSA_KEY_TYPE_HMAC); + psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&kattr, PSA_ALG_HMAC(PSA_ALG_SHA_256)); + + /* Import the MAC tag key part of derived key, that is the part that starts + * after BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE and has length of + * BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE bytes. + */ + psa_ret = psa_import_key(&kattr, + &derived_key[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE], + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE, &kid); + psa_reset_key_attributes(&kattr); + if (psa_ret != PSA_SUCCESS) { + memset(derived_key, 0, sizeof(derived_key)); + BOOT_LOG_ERR("MAC key import failed %d", psa_ret); + return -1; + } + + /* Verify the MAC tag of the random encryption key */ + psa_ret = psa_mac_verify(kid, PSA_ALG_HMAC(PSA_ALG_SHA_256), + &buf[EC_CIPHERKEY_INDEX], BOOT_ENC_KEY_SIZE, + &buf[EC_TAG_INDEX], + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE); + psa_cleanup_ret = psa_destroy_key(kid); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("MAC key destruction failed %d", psa_cleanup_ret); + } + if (psa_ret != PSA_SUCCESS) { + memset(derived_key, 0, sizeof(derived_key)); + BOOT_LOG_ERR("MAC verification failed %d", psa_ret); + return -1; + } + + /* The derived key is used in AES decryption of random key */ + psa_set_key_type(&kattr, PSA_KEY_TYPE_AES); + psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&kattr, PSA_ALG_CTR); + + /* Import the AES partition of derived key, the first 16 bytes */ + psa_ret = psa_import_key(&kattr, &derived_key[0], + BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE, &kid); + memset(derived_key, 0, sizeof(derived_key)); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES key import failed %d", psa_ret); + return -1; + } + + /* Decrypt the random AES encryption key with AES and the key obtained + * at derivation. */ + memset(&iv_and_key[0], 0, PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR)); + memcpy(&iv_and_key[PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR)], + &buf[EC_CIPHERKEY_INDEX], + sizeof(iv_and_key) - PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR)); + + len = 0; + psa_ret = psa_cipher_decrypt(kid, PSA_ALG_CTR, iv_and_key, sizeof(iv_and_key), + enckey, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE, &len); + memset(iv_and_key, 0, sizeof(iv_and_key)); + psa_cleanup_ret = psa_destroy_key(kid); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("AES key destruction failed %d", psa_cleanup_ret); + } + if (psa_ret != PSA_SUCCESS || len != BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE) { + memset(enckey, 0, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE); + BOOT_LOG_ERR("Random key decryption failed %d", psa_ret); + return -1; + } + + return 0; +} + +int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, + const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c) +{ + int ret = 0; + psa_status_t psa_ret = PSA_ERROR_BAD_STATE; + psa_key_attributes_t kattr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t kid; + psa_cipher_operation_t psa_op; + size_t elen = 0; /* Decrypted length */ + + /* Fixme: calling psa_crypto_init multiple times is not a problem, + * yet the code here is only present because there is not general + * crypto init. */ + psa_ret = psa_crypto_init(); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("PSA crypto init failed %d", psa_ret); + ret = -1; + goto gone; + } + + psa_op = psa_cipher_operation_init(); + + /* Fixme: Import should happen when key is decrypted, but due to lack + * of key destruction there is no way to destroy key stored by + * psa other way than here. */ + psa_set_key_type(&kattr, PSA_KEY_TYPE_AES); + psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&kattr, PSA_ALG_CTR); + + psa_ret = psa_import_key(&kattr, ctx->key, BOOT_ENC_KEY_SIZE, &kid); + psa_reset_key_attributes(&kattr); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES enc import key failed %d", psa_ret); + ret = -1; + goto gone; + } + + /* This could be done with psa_cipher_decrypt one-shot operation, but + * multi-part operation is used to avoid re-allocating input buffer + * to account for IV in front of data. + */ + psa_ret = psa_cipher_encrypt_setup(&psa_op, kid, PSA_ALG_CTR); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES enc setup failed %d", psa_ret); + ret = -1; + goto gone_with_key; + } + + /* Fixme: hardcoded counter size, but it is hardcoded everywhere */ + psa_ret = psa_cipher_set_iv(&psa_op, counter, 16); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES enc IV set failed %d", psa_ret); + ret = -1; + goto gone_after_setup; + } + + psa_ret = psa_cipher_update(&psa_op, m, mlen, c, mlen, &elen); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES enc encryption failed %d", psa_ret); + ret = -1; + goto gone_after_setup; + } + +gone_after_setup: + psa_ret = psa_cipher_abort(&psa_op); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("AES enc cipher abort failed %d", psa_ret); + /* Intentionally not changing the ret */ + } +gone_with_key: + /* Fixme: Should be removed once key is shared by id */ + psa_ret = psa_destroy_key(kid); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("AES enc destroy key failed %d", psa_ret); + /* Intentionally not changing the ret */ + } +gone: + return ret; +} + +int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, + const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m) +{ + int ret = 0; + psa_status_t psa_ret = PSA_ERROR_BAD_STATE; + psa_key_attributes_t kattr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t kid; + psa_cipher_operation_t psa_op; + size_t dlen = 0; /* Decrypted length */ + + /* Fixme: the init should already happen before calling the function, but + * somehow it does not, for example when recovering in swap. + */ + psa_ret = psa_crypto_init(); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("PSA crypto init failed %d", psa_ret); + ret = -1; + goto gone; + } + + psa_op = psa_cipher_operation_init(); + + /* Fixme: Import should happen when key is decrypted, but due to lack + * of key destruction there is no way to destroy key stored by + * psa other way than here. */ + psa_set_key_type(&kattr, PSA_KEY_TYPE_AES); + psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&kattr, PSA_ALG_CTR); + + psa_ret = psa_import_key(&kattr, ctx->key, BOOT_ENC_KEY_SIZE, &kid); + psa_reset_key_attributes(&kattr); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES dec import key failed %d", psa_ret); + ret = -1; + goto gone; + } + + /* This could be done with psa_cipher_decrypt one-shot operation, but + * multi-part operation is used to avoid re-allocating input buffer + * to account for IV in front of data. + */ + psa_ret = psa_cipher_decrypt_setup(&psa_op, kid, PSA_ALG_CTR); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES dec setup failed %d", psa_ret); + ret = -1; + goto gone_with_key; + } + + /* Fixme: hardcoded counter size, but it is hardcoded everywhere */ + psa_ret = psa_cipher_set_iv(&psa_op, counter, 16); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES dec IV set failed %d", psa_ret); + ret = -1; + goto gone_after_setup; + } + + psa_ret = psa_cipher_update(&psa_op, c, clen, m, clen, &dlen); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES dec decryption failed %d", psa_ret); + ret = -1; + goto gone_after_setup; + } + +gone_after_setup: + psa_ret = psa_cipher_abort(&psa_op); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("PSA dec abort failed %d", psa_ret); + /* Intentionally not changing the ret */ + } +gone_with_key: + psa_ret = psa_destroy_key(kid); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("PSA dec key failed %d", psa_ret); + /* Intentionally not changing the ret */ + } +gone: + return ret; +} +#endif /* defined(MCUBOOT_ENC_IMAGES) */ diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 7a597d4c0..c3e8410f1 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -9,6 +9,11 @@ #include "mcuboot_config/mcuboot_config.h" +#if defined(CONFIG_NRF_SECURITY) +/* We are not really using the MBEDTLS but need the ASN.1 parsing funcitons */ +#define MBEDTLS_ASN1_PARSE_C +#endif + #ifdef MCUBOOT_SIGN_ED25519 #include "bootutil/sign_key.h" @@ -18,12 +23,16 @@ #include "bootutil_priv.h" #include "bootutil/crypto/common.h" +#define SHA512_LEN 64 +#define SHA256_LEN 32 +#define EDDSA_SIGNAGURE_LENGTH 64 + static const uint8_t ed25519_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x65\x70"; #define NUM_ED25519_BYTES 32 extern int ED25519_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[64], - const uint8_t public_key[32]); + const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], + const uint8_t public_key[NUM_ED25519_BYTES]); /* * Parse the public key used for signing. @@ -73,7 +82,8 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, uint8_t *pubkey; uint8_t *end; - if (hlen != 32 || slen != 64) { + if (!(hlen == SHA512_LEN || hlen == SHA256_LEN) || + slen != EDDSA_SIGNAGURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } @@ -87,7 +97,7 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, goto out; } - rc = ED25519_verify(hash, 32, sig, pubkey); + rc = ED25519_verify(hash, hlen, sig, pubkey); if (rc == 0) { /* if verify returns 0, there was an error. */ From 5721744229fe352fddd1e85aaf4b85acfabe166e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 1 Oct 2024 10:35:26 +0000 Subject: [PATCH 082/238] [nrf noup] Exclude PSA source on non-PSA crypto configuration fixup! [nrf noup] PSA configuration required changes Signed-off-by: Dominik Ermel --- boot/zephyr/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 8a2c97ead..8b877f32e 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -108,7 +108,7 @@ zephyr_library_sources( ${BOOT_DIR}/bootutil/src/fault_injection_hardening.c ) -if(DEFINED CONFIG_BOOT_ENCRYPT_X25519) +if(DEFINED CONFIG_BOOT_ENCRYPT_X25519 AND DEFINED CONFIG_BOOT_ED25519_PSA) zephyr_library_sources(${BOOT_DIR}/bootutil/src/encrypted_psa.c) endif() From 273c10638d3714bdf675d2be44cf6c8957f6249c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 2 Aug 2024 15:55:13 +0000 Subject: [PATCH 083/238] [nrf noup] bootutil: Provide support for SHA512 with ED25519 Use SHA512 directly calculated over image with the ED25519 signature. Signed-off-by: Dominik Ermel --- boot/zephyr/Kconfig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 264c08241..859d21454 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -79,7 +79,7 @@ config BOOT_PSA_IMG_HASH_ALG_SHA256_DEPENDENCIES config BOOT_ED25519_PSA_DEPENDENCIES bool - select PSA_WANT_ALG_SHA_256 + select PSA_WANT_ALG_SHA_256 if BOOT_IMG_HASH_ALG_SHA256 select PSA_WANT_ALG_SHA_512 select PSA_WANT_ALG_PURE_EDDSA select PSA_WANT_ECC_TWISTED_EDWARDS_255 @@ -228,6 +228,11 @@ config BOOT_SIGNATURE_TYPE_ED25519 bool "Edwards curve digital signatures using ed25519" select BOOT_ENCRYPTION_SUPPORT select BOOT_IMG_HASH_ALG_SHA256_ALLOW + select BOOT_IMG_HASH_ALG_SHA512_ALLOW + help + This is ed25519 signature calculated over SHA512 of SHA256 of application + image; that is not completely correct approach as the SHA512 should be + rather directly calculated over an image. if BOOT_SIGNATURE_TYPE_ED25519 choice BOOT_ED25519_IMPLEMENTATION From e1591c0ca0cfb89cb643fe7b6bede40a25596c18 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 5 Sep 2024 10:53:17 +0000 Subject: [PATCH 084/238] [nrf noup] bootutil: Enable hash calculation directly on storage The commit add support for passing storage device address space to hash calculation functions, which allows to use hardware accelerated hash calculation on storage. This feature only works when image encryption is not enabled and all slots are defined within internal storage of device. The feature is enabled using Kconfig option CONFIG_BOOT_IMG_HASH_DIRECTLY_ON_STORAGE Signed-off-by: Dominik Ermel --- boot/bootutil/src/image_validate.c | 15 ++++++++++++--- boot/zephyr/Kconfig | 16 ++++++++++++++++ .../include/mcuboot_config/mcuboot_config.h | 7 +++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index a6155f7b0..12a9a7188 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -77,13 +77,15 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, uint8_t *seed, int seed_len) { bootutil_sha_context sha_ctx; - uint32_t blk_sz; uint32_t size; uint16_t hdr_size; - uint32_t off; - int rc; uint32_t blk_off; uint32_t tlv_off; +#if !defined(MCUBOOT_HASH_STORAGE_DIRECTLY) + int rc; + uint32_t off; + uint32_t blk_sz; +#endif #if (BOOT_IMAGE_NUMBER == 1) || !defined(MCUBOOT_ENC_IMAGES) || \ defined(MCUBOOT_RAM_LOAD) @@ -126,6 +128,12 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, /* If protected TLVs are present they are also hashed. */ size += hdr->ih_protect_tlv_size; +#ifdef MCUBOOT_HASH_STORAGE_DIRECTLY + /* No chunk loading, storage is mapped to address space and can + * be directly given to hashing function. + */ + bootutil_sha_update(&sha_ctx, (void *)flash_area_get_off(fap), size); +#else /* MCUBOOT_HASH_STORAGE_DIRECTLY */ #ifdef MCUBOOT_RAM_LOAD bootutil_sha_update(&sha_ctx, (void*)(IMAGE_RAM_BASE + hdr->ih_load_addr), @@ -170,6 +178,7 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, bootutil_sha_update(&sha_ctx, tmp_buf, blk_sz); } #endif /* MCUBOOT_RAM_LOAD */ +#endif /* MCUBOOT_HASH_STORAGE_DIRECTLY */ bootutil_sha_finish(&sha_ctx, hash_result); bootutil_sha_drop(&sha_ctx); diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 859d21454..acee064d0 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -146,6 +146,22 @@ config BOOT_IMG_HASH_ALG_SHA512_ALLOW help Hidden option set by configurations that allow SHA512 +config BOOT_IMG_HASH_DIRECTLY_ON_STORAGE + bool "Hash calculation functions access storage through address space" + depends on !BOOT_ENCRYPT_IMAGE + help + When possible to map storage device, at least for read operations, + to address space or RAM area, enabling this option allows hash + calculation functions to directly access the storage through that address + space or using its own DMA. This reduces flash read overhead done + by the MCUboot. + Notes: + - not supported when encrypted images are in use, because calculating + SHA requires image to be decrypted first, which is done to RAM. + - currently only supported on internal storage of devices; this + option will not work with devices that use external storage for + either of image slots. + choice BOOT_IMG_HASH_ALG prompt "Selected image hash algorithm" default BOOT_IMG_HASH_ALG_SHA256 if BOOT_IMG_HASH_ALG_SHA256_ALLOW diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 9d58436d2..4f31a623e 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -140,6 +140,13 @@ #define MCUBOOT_DECOMPRESS_IMAGES #endif +/* Invoke hashing functions directly on storage. This requires for device + * to be able to map storage to address space or RAM. + */ +#ifdef CONFIG_BOOT_IMG_HASH_DIRECTLY_ON_STORAGE +#define MCUBOOT_HASH_STORAGE_DIRECTLY +#endif + #ifdef CONFIG_BOOT_BOOTSTRAP #define MCUBOOT_BOOTSTRAP 1 #endif From de524e93b604d54541736875769c851ed6a3ed3e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 6 Sep 2024 16:16:28 +0000 Subject: [PATCH 085/238] [nrf noup] bootutil: PureEdDSA using ED25519 The commit adds support for PureEdDSA, which validates signature of image rather than hash. This is most secure, available, ED25519 usage in MCUboot, but due to requirement of PureEdDSA to be able to calculate signature at whole message at once, here image, it only works on setups where entire image can be mapped to device address space, so that PSA functions calculating the signature can see the whole image at once. This option is enabled with Kconfig option: CONFIG_BOOT_SIGNATURE_TYPE_PURE when the ED25519 signature type is already selected. Note that the option will enable SHA512 for calculating public key hash. Signed-off-by: Dominik Ermel --- boot/bootutil/include/bootutil/image.h | 3 + boot/bootutil/src/bootutil_priv.h | 3 + boot/bootutil/src/image_ed25519.c | 37 ++++++++ boot/bootutil/src/image_validate.c | 87 +++++++++++++++++-- boot/zephyr/Kconfig | 29 ++++++- .../include/mcuboot_config/mcuboot_config.h | 4 + 6 files changed, 155 insertions(+), 8 deletions(-) diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 9ede800a2..836712458 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -102,6 +102,9 @@ struct flash_area; #define IMAGE_TLV_ECDSA_SIG 0x22 /* ECDSA of hash output */ #define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */ #define IMAGE_TLV_ED25519 0x24 /* ed25519 of hash output */ +#define IMAGE_TLV_SIG_PURE 0x25 /* Whatever signature has been selected, it will be used + * as "pure" where signature is verified over entire + * image rather than hash of an image */ #define IMAGE_TLV_ENC_RSA2048 0x30 /* Key encrypted with RSA-OAEP-2048 */ #define IMAGE_TLV_ENC_KW 0x31 /* Key encrypted with AES-KW 128 or 256*/ #define IMAGE_TLV_ENC_EC256 0x32 /* Key encrypted with ECIES-EC256 */ diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h index 32f996e78..68e0595cf 100644 --- a/boot/bootutil/src/bootutil_priv.h +++ b/boot/bootutil/src/bootutil_priv.h @@ -262,6 +262,9 @@ struct boot_loader_state { fih_ret bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, uint8_t key_id); +fih_ret bootutil_verify_img(const uint8_t *img, uint32_t size, + uint8_t *sig, size_t slen, uint8_t key_id); + fih_ret boot_fih_memequal(const void *s1, const void *s2, size_t n); int boot_find_status(int image_index, const struct flash_area **fap); diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index c3e8410f1..984a58302 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -111,4 +111,41 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, FIH_RET(fih_rc); } +fih_ret +bootutil_verify_img(const uint8_t *img, uint32_t size, + uint8_t *sig, size_t slen, uint8_t key_id) +{ + int rc; + FIH_DECLARE(fih_rc, FIH_FAILURE); + uint8_t *pubkey; + uint8_t *end; + + if (slen != EDDSA_SIGNAGURE_LENGTH) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + + pubkey = (uint8_t *)bootutil_keys[key_id].key; + end = pubkey + *bootutil_keys[key_id].len; + + rc = bootutil_import_key(&pubkey, end); + if (rc) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + + rc = ED25519_verify(img, size, sig, pubkey); + + if (rc == 0) { + /* if verify returns 0, there was an error. */ + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + + FIH_SET(fih_rc, FIH_SUCCESS); +out: + + FIH_RET(fih_rc); +} + #endif /* MCUBOOT_SIGN_ED25519 */ diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 12a9a7188..1ba0f7b23 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -65,6 +65,7 @@ BOOT_LOG_MODULE_DECLARE(mcuboot); #include "bootutil_priv.h" +#ifndef MCUBOOT_SIGN_PURE /* * Compute SHA hash over the image. * (SHA384 if ECDSA-P384 is being used, @@ -184,6 +185,7 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, return 0; } +#endif /* * Currently, we only support being able to verify one type of @@ -370,6 +372,35 @@ bootutil_get_img_security_cnt(struct image_header *hdr, return 0; } +#if defined(MCUBOOT_SIGN_PURE) +/* Returns: + * 0 -- found + * 1 -- not found + * -1 -- failed for some reason + * + * Value of TLV does not matter, presence decides. + */ +static int bootutil_check_for_pure(const struct image_header *hdr, + const struct flash_area *fap) +{ + struct image_tlv_iter it; + uint32_t off; + uint16_t len; + int32_t rc; + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_SIG_PURE, false); + if (rc) { + return rc; + } + + /* Search for the TLV */ + rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); + + return rc; +} +#endif + + #ifndef ALLOW_ROGUE_TLVS /* * The following list of TLVs are the only entries allowed in the unprotected @@ -386,6 +417,9 @@ static const uint16_t allowed_unprot_tlvs[] = { IMAGE_TLV_ECDSA_SIG, IMAGE_TLV_RSA3072_PSS, IMAGE_TLV_ED25519, +#if defined(MCUBOOT_SIGN_PURE) + IMAGE_TLV_SIG_PURE, +#endif IMAGE_TLV_ENC_RSA2048, IMAGE_TLV_ENC_KW, IMAGE_TLV_ENC_EC256, @@ -408,7 +442,6 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, uint32_t off; uint16_t len; uint16_t type; - int image_hash_valid = 0; #ifdef EXPECTED_SIG_TLV FIH_DECLARE(valid_signature, FIH_FAILURE); #ifndef MCUBOOT_BUILTIN_KEY @@ -425,7 +458,10 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, #endif /* EXPECTED_SIG_TLV */ struct image_tlv_iter it; uint8_t buf[SIG_BUF_SIZE]; +#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) + int image_hash_valid = 0; uint8_t hash[IMAGE_HASH_SIZE]; +#endif int rc = 0; FIH_DECLARE(fih_rc, FIH_FAILURE); #ifdef MCUBOOT_HW_ROLLBACK_PROT @@ -494,6 +530,7 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } #endif +#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) rc = bootutil_img_hash(enc_state, image_index, hdr, fap, tmp_buf, tmp_buf_sz, hash, seed, seed_len); if (rc) { @@ -503,6 +540,15 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, if (out_hash) { memcpy(out_hash, hash, IMAGE_HASH_SIZE); } +#endif + +#if defined(MCUBOOT_SIGN_PURE) + /* If Pure type signature is expected then it has to be there */ + rc = bootutil_check_for_pure(hdr, fap); + if (rc != 0) { + goto out; + } +#endif rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false); if (rc) { @@ -546,8 +592,10 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } } #endif - - if (type == EXPECTED_HASH_TLV) { + switch(type) { +#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) + case EXPECTED_HASH_TLV: + { /* Verify the image hash. This must always be present. */ if (len != sizeof(hash)) { rc = -1; @@ -565,8 +613,12 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } image_hash_valid = 1; + break; + } +#endif /* defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) */ #ifdef EXPECTED_KEY_TLV - } else if (type == EXPECTED_KEY_TLV) { + case EXPECTED_KEY_TLV: + { /* * Determine which key we should be checking. */ @@ -591,9 +643,12 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, * The key may not be found, which is acceptable. There * can be multiple signatures, each preceded by a key. */ + break; + } #endif /* EXPECTED_KEY_TLV */ #ifdef EXPECTED_SIG_TLV - } else if (type == EXPECTED_SIG_TLV) { + case EXPECTED_SIG_TLV: + { /* Ignore this signature if it is out of bounds. */ if (key_id < 0 || key_id >= bootutil_key_cnt) { key_id = -1; @@ -607,12 +662,25 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, if (rc) { goto out; } +#ifndef MCUBOOT_SIGN_PURE FIH_CALL(bootutil_verify_sig, valid_signature, hash, sizeof(hash), buf, len, key_id); +#else + /* Directly check signature on the image, by using the mapping of + * a device to memory. The pointer is beginning of image in flash, + * so offset of area, the range is header + image + protected tlvs. + */ + FIH_CALL(bootutil_verify_img, valid_signature, (void *)flash_area_get_off(fap), + hdr->ih_hdr_size + hdr->ih_img_size + hdr->ih_protect_tlv_size, + buf, len, key_id); +#endif key_id = -1; + break; + } #endif /* EXPECTED_SIG_TLV */ #ifdef MCUBOOT_HW_ROLLBACK_PROT - } else if (type == IMAGE_TLV_SEC_CNT) { + case IMAGE_TLV_SEC_CNT: + { /* * Verify the image's security counter. * This must always be present. @@ -647,14 +715,21 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, /* The image's security counter has been successfully verified. */ security_counter_valid = fih_rc; + break; + } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ } } +#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) rc = !image_hash_valid; if (rc) { goto out; } +#elif defined(MCUBOOT_SIGN_PURE) + /* This returns true on EQ, rc is err on non-0 */ + rc = !FIH_EQ(valid_signature, FIH_SUCCESS); +#endif #ifdef EXPECTED_SIG_TLV FIH_SET(fih_rc, valid_signature); #endif diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index acee064d0..70da5d010 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -192,6 +192,14 @@ config BOOT_IMG_HASH_ALG_SHA512 endchoice # BOOT_IMG_HASH_ALG +config BOOT_SIGNATURE_TYPE_PURE_ALLOW + bool + help + Hidden option set by configurations that allow Pure variant, + for example ed25519. The pure variant means that image + signature is calculated over entire image instead of hash + of an image. + choice BOOT_SIGNATURE_TYPE prompt "Signature type" default BOOT_SIGNATURE_TYPE_ED25519 if BOARD_NRF54L15PDK_NRF54L15_CPUAPP @@ -242,15 +250,32 @@ endif config BOOT_SIGNATURE_TYPE_ED25519 bool "Edwards curve digital signatures using ed25519" - select BOOT_ENCRYPTION_SUPPORT - select BOOT_IMG_HASH_ALG_SHA256_ALLOW + select BOOT_ENCRYPTION_SUPPORT if !BOOT_SIGNATURE_TYPE_PURE + select BOOT_IMG_HASH_ALG_SHA256_ALLOW if !BOOT_SIGNATURE_TYPE_PURE + # The SHA is used only for key hashing, not for images. select BOOT_IMG_HASH_ALG_SHA512_ALLOW + select BOOT_SIGNATURE_TYPE_PURE_ALLOW help This is ed25519 signature calculated over SHA512 of SHA256 of application image; that is not completely correct approach as the SHA512 should be rather directly calculated over an image. + Select BOOT_SIGNATURE_TYPE_PURE to have a PureEdDSA calculating image + signature directly on image, rather than hash of the image. if BOOT_SIGNATURE_TYPE_ED25519 + +config BOOT_SIGNATURE_TYPE_PURE + bool "Use Pure signature of image" + depends on BOOT_SIGNATURE_TYPE_PURE_ALLOW + help + The Pure signature is calculated directly over image rather than + hash of an image. + This is more secure signature, specifically if hardware can do the + verification without need to share key. + Note that this requires that all slots for which signature is to be + verified need to be accessible through memory address space that + cryptography can access. + choice BOOT_ED25519_IMPLEMENTATION prompt "Ecdsa implementation" default BOOT_ED25519_TINYCRYPT diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 4f31a623e..f04be2434 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -147,6 +147,10 @@ #define MCUBOOT_HASH_STORAGE_DIRECTLY #endif +#ifdef CONFIG_BOOT_SIGNATURE_TYPE_PURE +#define MCUBOOT_SIGN_PURE +#endif + #ifdef CONFIG_BOOT_BOOTSTRAP #define MCUBOOT_BOOTSTRAP 1 #endif From f79e6db32c897f47f7e630f843bb97063379db2b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 2 Oct 2024 15:03:50 +0000 Subject: [PATCH 086/238] [nrf noup] There is only one SHA supported at once fixup! [nrf noup] PSA implementation of x25519 and ed25519 verification And fixing typos. Signed-off-by: Dominik Ermel --- boot/bootutil/src/image_ed25519.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 984a58302..07ac36265 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -22,16 +22,15 @@ #include "bootutil_priv.h" #include "bootutil/crypto/common.h" +#include "bootutil/crypto/sha.h" -#define SHA512_LEN 64 -#define SHA256_LEN 32 -#define EDDSA_SIGNAGURE_LENGTH 64 +#define EDDSA_SIGNATURE_LENGTH 64 static const uint8_t ed25519_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x65\x70"; #define NUM_ED25519_BYTES 32 extern int ED25519_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], + const uint8_t signature[EDDSA_SIGNATURE_LENGTH], const uint8_t public_key[NUM_ED25519_BYTES]); /* @@ -82,8 +81,7 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, uint8_t *pubkey; uint8_t *end; - if (!(hlen == SHA512_LEN || hlen == SHA256_LEN) || - slen != EDDSA_SIGNAGURE_LENGTH) { + if (hlen != IMAGE_HASH_SIZE || slen != EDDSA_SIGNATURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } @@ -97,7 +95,7 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, goto out; } - rc = ED25519_verify(hash, hlen, sig, pubkey); + rc = ED25519_verify(hash, IMAGE_HASH_SIZE, sig, pubkey); if (rc == 0) { /* if verify returns 0, there was an error. */ From 763edd653b1b9a5efd643221333e9ea16767da11 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 2 Oct 2024 15:42:00 +0000 Subject: [PATCH 087/238] [nrf noup] bootutil: Fix typo in identifier fixup! [nrf noup] bootutil: PureEdDSA using ED25519 Signed-off-by: Dominik Ermel --- boot/bootutil/src/image_ed25519.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 07ac36265..40d494bcf 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -118,7 +118,7 @@ bootutil_verify_img(const uint8_t *img, uint32_t size, uint8_t *pubkey; uint8_t *end; - if (slen != EDDSA_SIGNAGURE_LENGTH) { + if (slen != EDDSA_SIGNATURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } From 4927e3974f66ea30e8503a74c94f62d84a5780d3 Mon Sep 17 00:00:00 2001 From: Mateusz Michalek Date: Fri, 9 Aug 2024 12:16:40 +0200 Subject: [PATCH 088/238] [nrf fromlist] scripts: imgtool: compression Adds LZMA2 compression to imgtool. Python lzma library is unable to compress with proper parameters while using "ALONE" container, therefore 2 header bytes are calculated and added to payload by imgtool. Upstream PR: https://github.com/mcu-tools/mcuboot/pull/2038 Signed-off-by: Mateusz Michalek --- scripts/imgtool/image.py | 71 ++++++++++++++++++++++++++++++++---- scripts/imgtool/main.py | 79 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 135 insertions(+), 15 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index 53b19ef1d..1f43ccf82 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -20,7 +20,15 @@ Image signing and management. """ +from . import version as versmod +from .boot_record import create_sw_component_data +import click +import copy +from enum import Enum +import array +from intelhex import IntelHex import hashlib +import array import os.path import struct from enum import Enum @@ -60,6 +68,8 @@ 'NON_BOOTABLE': 0x0000010, 'RAM_LOAD': 0x0000020, 'ROM_FIXED': 0x0000100, + 'COMPRESSED_LZMA1': 0x0000200, + 'COMPRESSED_LZMA2': 0x0000400, } TLV_VALUES = { @@ -79,6 +89,9 @@ 'DEPENDENCY': 0x40, 'SEC_CNT': 0x50, 'BOOT_RECORD': 0x60, + 'DECOMP_SIZE': 0x70, + 'DECOMP_SHA': 0x71, + 'DECOMP_SIGNATURE': 0x72, } TLV_SIZE = 4 @@ -237,6 +250,9 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, if load_addr and rom_fixed: raise click.UsageError("Can not set rom_fixed and load_addr at the same time") + self.image_hash = None + self.image_size = None + self.signature = None self.version = version or versmod.decode_version("0") self.header_size = header_size self.pad_header = pad_header @@ -252,6 +268,7 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, self.rom_fixed = rom_fixed self.erased_val = 0xff if erased_val is None else int(erased_val, 0) self.payload = [] + self.infile_data = [] self.enckey = None self.save_enctlv = save_enctlv self.enctlv_len = 0 @@ -300,19 +317,39 @@ def __repr__(self): self.__class__.__name__, len(self.payload)) - def load(self, path): + def load(self, path, compression_header=None): """Load an image from a given file""" ext = os.path.splitext(path)[1][1:].lower() try: if ext == INTEL_HEX_EXT: ih = IntelHex(path) - self.payload = ih.tobinarray() + self.infile_data = ih.tobinarray() + self.payload = copy.copy(self.infile_data) self.base_addr = ih.minaddr() else: with open(path, 'rb') as f: - self.payload = f.read() + self.infile_data = f.read() + self.payload = copy.copy(self.infile_data) + if compression_header is not None: + self.payload = compression_header + self.payload except FileNotFoundError: raise click.UsageError("Input file not found") + self.image_size = len(self.payload) + + # Add the image header if needed. + if self.pad_header and self.header_size > 0: + if self.base_addr: + # Adjust base_addr for new header + self.base_addr -= self.header_size + self.payload = bytes([self.erased_val] * self.header_size) + \ + self.payload + + self.check_header() + + def load_compressed(self, data, compression_header): + """Load an image from buffer""" + self.payload = compression_header + data + self.image_size = len(self.payload) # Add the image header if needed. if self.pad_header and self.header_size > 0: @@ -407,7 +444,8 @@ def ecies_hkdf(self, enckey, plainkey): return cipherkey, ciphermac, pubk def create(self, key, public_key_format, enckey, dependencies=None, - sw_type=None, custom_tlvs=None, encrypt_keylen=128, clear=False, + sw_type=None, custom_tlvs=None, compression_tlvs=None, + compression_type=None, encrypt_keylen=128, clear=False, fixed_sig=None, pub_key=None, vector_to_sign=None, user_sha='auto'): self.enckey = enckey @@ -470,6 +508,9 @@ def create(self, key, public_key_format, enckey, dependencies=None, dependencies_num = len(dependencies[DEP_IMAGES_KEY]) protected_tlv_size += (dependencies_num * 16) + if compression_tlvs is not None: + for value in compression_tlvs.values(): + protected_tlv_size += TLV_SIZE + len(value) if custom_tlvs is not None: for value in custom_tlvs.values(): protected_tlv_size += TLV_SIZE + len(value) @@ -491,11 +532,15 @@ def create(self, key, public_key_format, enckey, dependencies=None, else: self.payload.extend(pad) + compression_flags = 0x0 + if compression_tlvs is not None: + if compression_type == "lzma2": + compression_flags = IMAGE_F['COMPRESSED_LZMA2'] # This adds the header to the payload as well if encrypt_keylen == 256: - self.add_header(enckey, protected_tlv_size, 256) + self.add_header(enckey, protected_tlv_size, compression_flags, 256) else: - self.add_header(enckey, protected_tlv_size) + self.add_header(enckey, protected_tlv_size, compression_flags) prot_tlv = TLV(self.endian, TLV_PROT_INFO_MAGIC) @@ -525,6 +570,9 @@ def create(self, key, public_key_format, enckey, dependencies=None, ) prot_tlv.add('DEPENDENCY', payload) + if compression_tlvs is not None: + for tag, value in compression_tlvs.items(): + prot_tlv.add(tag, value) if custom_tlvs is not None: for tag, value in custom_tlvs.items(): prot_tlv.add(tag, value) @@ -543,6 +591,7 @@ def create(self, key, public_key_format, enckey, dependencies=None, digest = sha.digest() message = digest; tlv.add(hash_tlv, digest) + self.image_hash = digest if vector_to_sign == 'payload': # Stop amending data to the image @@ -622,10 +671,16 @@ def create(self, key, public_key_format, enckey, dependencies=None, self.check_trailer() + def get_struct_endian(self): + return STRUCT_ENDIAN_DICT[self.endian] + def get_signature(self): return self.signature - def add_header(self, enckey, protected_tlv_size, aes_length=128): + def get_infile_data(self): + return self.infile_data + + def add_header(self, enckey, protected_tlv_size, compression_flags, aes_length=128): """Install the image header.""" flags = 0 @@ -663,7 +718,7 @@ def add_header(self, enckey, protected_tlv_size, aes_length=128): protected_tlv_size, # TLV Info header + # Protected TLVs len(self.payload) - self.header_size, # ImageSz - flags, + flags | compression_flags, self.version.major, self.version.minor or 0, self.version.revision or 0, diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index 848fd3110..9e91582b9 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -22,6 +22,10 @@ import getpass import imgtool.keys as keys import sys +import struct +import os +import lzma +import hashlib import base64 from imgtool import image, imgtool_version from imgtool.version import decode_version @@ -29,6 +33,13 @@ from .keys import ( RSAUsageError, ECDSAUsageError, Ed25519UsageError, X25519UsageError) +comp_default_dictsize=131072 +comp_default_pb=2 +comp_default_lc=3 +comp_default_lp=1 +comp_default_preset=9 + + MIN_PYTHON_VERSION = (3, 6) if sys.version_info < MIN_PYTHON_VERSION: sys.exit("Python %s.%s or newer is required by imgtool." @@ -300,6 +311,14 @@ def get_dependencies(ctx, param, value): dependencies[image.DEP_VERSIONS_KEY] = versions return dependencies +def create_lzma2_header(dictsize, pb, lc, lp): + header = bytearray() + for i in range(0, 40): + if dictsize <= ((2 | ((i) & 1)) << int((i) / 2 + 11)): + header.append(i) + break + header.append( ( pb * 5 + lp) * 9 + lc) + return header class BasedIntParamType(click.ParamType): name = 'integer' @@ -343,6 +362,11 @@ def convert(self, value, param, ctx): type=click.Choice(['128', '256']), help='When encrypting the image using AES, select a 128 bit or ' '256 bit key len.') +@click.option('--compression', default='disabled', + type=click.Choice(['disabled', 'lzma2']), + help='Enable image compression using specified type. ' + 'Will fall back without image compression automatically ' + 'if the compression increases the image size.') @click.option('-c', '--clear', required=False, is_flag=True, default=False, help='Output a non-encrypted image with encryption capabilities,' 'so it can be installed in the primary slot, and encrypted ' @@ -414,10 +438,11 @@ def convert(self, value, param, ctx): .hex extension, otherwise binary format is used''') def sign(key, public_key_format, align, version, pad_sig, header_size, pad_header, slot_size, pad, confirm, max_sectors, overwrite_only, - endian, encrypt_keylen, encrypt, infile, outfile, dependencies, - load_addr, hex_addr, erased_val, save_enctlv, security_counter, - boot_record, custom_tlv, rom_fixed, max_align, clear, fix_sig, - fix_sig_pubkey, sig_out, user_sha, vector_to_sign, non_bootable): + endian, encrypt_keylen, encrypt, compression, infile, outfile, + dependencies, load_addr, hex_addr, erased_val, save_enctlv, + security_counter, boot_record, custom_tlv, rom_fixed, max_align, + clear, fix_sig, fix_sig_pubkey, sig_out, user_sha, vector_to_sign, + non_bootable): if confirm: # Confirmed but non-padded images don't make much sense, because @@ -431,6 +456,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, erased_val=erased_val, save_enctlv=save_enctlv, security_counter=security_counter, max_align=max_align, non_bootable=non_bootable) + compression_tlvs = {} img.load(infile) key = load_key(key) if key else None enckey = load_key(encrypt) if encrypt else None @@ -484,10 +510,49 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, } img.create(key, public_key_format, enckey, dependencies, boot_record, - custom_tlvs, int(encrypt_keylen), clear, baked_signature, - pub_key, vector_to_sign, user_sha) + custom_tlvs, compression_tlvs, int(encrypt_keylen), clear, + baked_signature, pub_key, vector_to_sign, user_sha) + + if compression == "lzma2" : + compressed_img = image.Image(version=decode_version(version), + header_size=header_size, pad_header=pad_header, + pad=pad, confirm=confirm, align=int(align), + slot_size=slot_size, max_sectors=max_sectors, + overwrite_only=overwrite_only, endian=endian, + load_addr=load_addr, rom_fixed=rom_fixed, + erased_val=erased_val, save_enctlv=save_enctlv, + security_counter=security_counter, max_align=max_align) + compression_filters = [ + {"id": lzma.FILTER_LZMA2, "preset": comp_default_preset, + "dict_size": comp_default_dictsize, "lp": comp_default_lp, + "lc": comp_default_lc} + ] + compressed_data = lzma.compress(img.get_infile_data(),filters=compression_filters, + format=lzma.FORMAT_RAW) + uncompressed_size = len(img.get_infile_data()) + compressed_size = len(compressed_data) + print("compressed image size:", compressed_size, + "bytes\noriginal image size:", uncompressed_size, "bytes") + compression_tlvs["DECOMP_SIZE"] = struct.pack( + img.get_struct_endian() + 'L', img.image_size) + compression_tlvs["DECOMP_SHA"] = img.image_hash + compression_tlvs_size = len(compression_tlvs["DECOMP_SIZE"]) + compression_tlvs_size += len(compression_tlvs["DECOMP_SHA"]) + if img.get_signature() is not None and img.get_signature() != "" : + compression_tlvs["DECOMP_SIGNATURE"] = img.get_signature() + compression_tlvs_size += len(compression_tlvs["DECOMP_SIGNATURE"]) + if (compressed_size + compression_tlvs_size) < uncompressed_size: + compression_header = create_lzma2_header( + dictsize = comp_default_dictsize, pb = comp_default_pb, + lc = comp_default_lc, lp = comp_default_lp) + compressed_img.load_compressed(compressed_data, compression_header) + compressed_img.base_addr = img.base_addr + compressed_img.create(key, public_key_format, enckey, + dependencies, boot_record, custom_tlvs, compression_tlvs, + compression, int(encrypt_keylen), clear, baked_signature, + pub_key, vector_to_sign) + img = compressed_img img.save(outfile, hex_addr) - if sig_out is not None: new_signature = img.get_signature() save_signature(sig_out, new_signature) From 3909498f76f91c5b8a95ea38d4c7084a03459a55 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 2 Oct 2024 14:05:32 +0100 Subject: [PATCH 089/238] [nrf noup] boot: zephyr: kconfig: Select PM_USE_CONFIG_SRAM_SIZE when needed fixup! [nrf noup] zephyr: Add support for compressed image updates Selects this Kconfig when compression is enabled for nrf54l15 Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 70da5d010..75b689d0f 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -907,6 +907,7 @@ if BOOT_DECOMPRESSION_SUPPORT menuconfig BOOT_DECOMPRESSION bool "Decompression" select NRF_COMPRESS_CLEANUP + select PM_USE_CONFIG_SRAM_SIZE if SOC_NRF54L15_CPUAPP help If enabled, will include support for compressed images being loaded to the secondary slot which then get decompressed into the primary slot. This mode allows the secondary slot to From 9101a24660a434d4fa26fd7674c4e74f8e2ff2b2 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 1 Oct 2024 15:39:31 +0000 Subject: [PATCH 090/238] [nrf noup] Add missing selection of MBEDTLS_PSA_CRYPTO_C fixup! [nrf noup] PSA configuration required changes Signed-off-by: Dominik Ermel --- boot/zephyr/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 75b689d0f..e20f61158 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -32,6 +32,7 @@ config BOOT_USE_PSA_CRYPTO default y if NRF_SECURITY # This is counter intuitive but that is how PSA heap is enabled. select MBEDTLS_ENABLE_HEAP + select MBEDTLS_PSA_CRYPTO_C help Hidden option set if using PSA crypt for cryptography functionality From 112b13cea3399b021fc4c6668db41e0ae2fa691c Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 091/238] Revert "[nrf noup] Add missing selection of MBEDTLS_PSA_CRYPTO_C" This reverts commit 9101a24660a434d4fa26fd7674c4e74f8e2ff2b2. --- boot/zephyr/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index e20f61158..75b689d0f 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -32,7 +32,6 @@ config BOOT_USE_PSA_CRYPTO default y if NRF_SECURITY # This is counter intuitive but that is how PSA heap is enabled. select MBEDTLS_ENABLE_HEAP - select MBEDTLS_PSA_CRYPTO_C help Hidden option set if using PSA crypt for cryptography functionality From ecba2539af68da8cf81b53d6f4c31436c7f2a071 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 092/238] Revert "[nrf noup] boot: zephyr: kconfig: Select PM_USE_CONFIG_SRAM_SIZE when needed" This reverts commit 3909498f76f91c5b8a95ea38d4c7084a03459a55. --- boot/zephyr/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 75b689d0f..70da5d010 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -907,7 +907,6 @@ if BOOT_DECOMPRESSION_SUPPORT menuconfig BOOT_DECOMPRESSION bool "Decompression" select NRF_COMPRESS_CLEANUP - select PM_USE_CONFIG_SRAM_SIZE if SOC_NRF54L15_CPUAPP help If enabled, will include support for compressed images being loaded to the secondary slot which then get decompressed into the primary slot. This mode allows the secondary slot to From d406289b0efe7b0108b147346409d43058cfceab Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 093/238] Revert "[nrf fromlist] scripts: imgtool: compression" This reverts commit 4927e3974f66ea30e8503a74c94f62d84a5780d3. --- scripts/imgtool/image.py | 71 ++++-------------------------------- scripts/imgtool/main.py | 79 ++++------------------------------------ 2 files changed, 15 insertions(+), 135 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index 1f43ccf82..53b19ef1d 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -20,15 +20,7 @@ Image signing and management. """ -from . import version as versmod -from .boot_record import create_sw_component_data -import click -import copy -from enum import Enum -import array -from intelhex import IntelHex import hashlib -import array import os.path import struct from enum import Enum @@ -68,8 +60,6 @@ 'NON_BOOTABLE': 0x0000010, 'RAM_LOAD': 0x0000020, 'ROM_FIXED': 0x0000100, - 'COMPRESSED_LZMA1': 0x0000200, - 'COMPRESSED_LZMA2': 0x0000400, } TLV_VALUES = { @@ -89,9 +79,6 @@ 'DEPENDENCY': 0x40, 'SEC_CNT': 0x50, 'BOOT_RECORD': 0x60, - 'DECOMP_SIZE': 0x70, - 'DECOMP_SHA': 0x71, - 'DECOMP_SIGNATURE': 0x72, } TLV_SIZE = 4 @@ -250,9 +237,6 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, if load_addr and rom_fixed: raise click.UsageError("Can not set rom_fixed and load_addr at the same time") - self.image_hash = None - self.image_size = None - self.signature = None self.version = version or versmod.decode_version("0") self.header_size = header_size self.pad_header = pad_header @@ -268,7 +252,6 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, self.rom_fixed = rom_fixed self.erased_val = 0xff if erased_val is None else int(erased_val, 0) self.payload = [] - self.infile_data = [] self.enckey = None self.save_enctlv = save_enctlv self.enctlv_len = 0 @@ -317,39 +300,19 @@ def __repr__(self): self.__class__.__name__, len(self.payload)) - def load(self, path, compression_header=None): + def load(self, path): """Load an image from a given file""" ext = os.path.splitext(path)[1][1:].lower() try: if ext == INTEL_HEX_EXT: ih = IntelHex(path) - self.infile_data = ih.tobinarray() - self.payload = copy.copy(self.infile_data) + self.payload = ih.tobinarray() self.base_addr = ih.minaddr() else: with open(path, 'rb') as f: - self.infile_data = f.read() - self.payload = copy.copy(self.infile_data) - if compression_header is not None: - self.payload = compression_header + self.payload + self.payload = f.read() except FileNotFoundError: raise click.UsageError("Input file not found") - self.image_size = len(self.payload) - - # Add the image header if needed. - if self.pad_header and self.header_size > 0: - if self.base_addr: - # Adjust base_addr for new header - self.base_addr -= self.header_size - self.payload = bytes([self.erased_val] * self.header_size) + \ - self.payload - - self.check_header() - - def load_compressed(self, data, compression_header): - """Load an image from buffer""" - self.payload = compression_header + data - self.image_size = len(self.payload) # Add the image header if needed. if self.pad_header and self.header_size > 0: @@ -444,8 +407,7 @@ def ecies_hkdf(self, enckey, plainkey): return cipherkey, ciphermac, pubk def create(self, key, public_key_format, enckey, dependencies=None, - sw_type=None, custom_tlvs=None, compression_tlvs=None, - compression_type=None, encrypt_keylen=128, clear=False, + sw_type=None, custom_tlvs=None, encrypt_keylen=128, clear=False, fixed_sig=None, pub_key=None, vector_to_sign=None, user_sha='auto'): self.enckey = enckey @@ -508,9 +470,6 @@ def create(self, key, public_key_format, enckey, dependencies=None, dependencies_num = len(dependencies[DEP_IMAGES_KEY]) protected_tlv_size += (dependencies_num * 16) - if compression_tlvs is not None: - for value in compression_tlvs.values(): - protected_tlv_size += TLV_SIZE + len(value) if custom_tlvs is not None: for value in custom_tlvs.values(): protected_tlv_size += TLV_SIZE + len(value) @@ -532,15 +491,11 @@ def create(self, key, public_key_format, enckey, dependencies=None, else: self.payload.extend(pad) - compression_flags = 0x0 - if compression_tlvs is not None: - if compression_type == "lzma2": - compression_flags = IMAGE_F['COMPRESSED_LZMA2'] # This adds the header to the payload as well if encrypt_keylen == 256: - self.add_header(enckey, protected_tlv_size, compression_flags, 256) + self.add_header(enckey, protected_tlv_size, 256) else: - self.add_header(enckey, protected_tlv_size, compression_flags) + self.add_header(enckey, protected_tlv_size) prot_tlv = TLV(self.endian, TLV_PROT_INFO_MAGIC) @@ -570,9 +525,6 @@ def create(self, key, public_key_format, enckey, dependencies=None, ) prot_tlv.add('DEPENDENCY', payload) - if compression_tlvs is not None: - for tag, value in compression_tlvs.items(): - prot_tlv.add(tag, value) if custom_tlvs is not None: for tag, value in custom_tlvs.items(): prot_tlv.add(tag, value) @@ -591,7 +543,6 @@ def create(self, key, public_key_format, enckey, dependencies=None, digest = sha.digest() message = digest; tlv.add(hash_tlv, digest) - self.image_hash = digest if vector_to_sign == 'payload': # Stop amending data to the image @@ -671,16 +622,10 @@ def create(self, key, public_key_format, enckey, dependencies=None, self.check_trailer() - def get_struct_endian(self): - return STRUCT_ENDIAN_DICT[self.endian] - def get_signature(self): return self.signature - def get_infile_data(self): - return self.infile_data - - def add_header(self, enckey, protected_tlv_size, compression_flags, aes_length=128): + def add_header(self, enckey, protected_tlv_size, aes_length=128): """Install the image header.""" flags = 0 @@ -718,7 +663,7 @@ def add_header(self, enckey, protected_tlv_size, compression_flags, aes_length=1 protected_tlv_size, # TLV Info header + # Protected TLVs len(self.payload) - self.header_size, # ImageSz - flags | compression_flags, + flags, self.version.major, self.version.minor or 0, self.version.revision or 0, diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index 9e91582b9..848fd3110 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -22,10 +22,6 @@ import getpass import imgtool.keys as keys import sys -import struct -import os -import lzma -import hashlib import base64 from imgtool import image, imgtool_version from imgtool.version import decode_version @@ -33,13 +29,6 @@ from .keys import ( RSAUsageError, ECDSAUsageError, Ed25519UsageError, X25519UsageError) -comp_default_dictsize=131072 -comp_default_pb=2 -comp_default_lc=3 -comp_default_lp=1 -comp_default_preset=9 - - MIN_PYTHON_VERSION = (3, 6) if sys.version_info < MIN_PYTHON_VERSION: sys.exit("Python %s.%s or newer is required by imgtool." @@ -311,14 +300,6 @@ def get_dependencies(ctx, param, value): dependencies[image.DEP_VERSIONS_KEY] = versions return dependencies -def create_lzma2_header(dictsize, pb, lc, lp): - header = bytearray() - for i in range(0, 40): - if dictsize <= ((2 | ((i) & 1)) << int((i) / 2 + 11)): - header.append(i) - break - header.append( ( pb * 5 + lp) * 9 + lc) - return header class BasedIntParamType(click.ParamType): name = 'integer' @@ -362,11 +343,6 @@ def convert(self, value, param, ctx): type=click.Choice(['128', '256']), help='When encrypting the image using AES, select a 128 bit or ' '256 bit key len.') -@click.option('--compression', default='disabled', - type=click.Choice(['disabled', 'lzma2']), - help='Enable image compression using specified type. ' - 'Will fall back without image compression automatically ' - 'if the compression increases the image size.') @click.option('-c', '--clear', required=False, is_flag=True, default=False, help='Output a non-encrypted image with encryption capabilities,' 'so it can be installed in the primary slot, and encrypted ' @@ -438,11 +414,10 @@ def convert(self, value, param, ctx): .hex extension, otherwise binary format is used''') def sign(key, public_key_format, align, version, pad_sig, header_size, pad_header, slot_size, pad, confirm, max_sectors, overwrite_only, - endian, encrypt_keylen, encrypt, compression, infile, outfile, - dependencies, load_addr, hex_addr, erased_val, save_enctlv, - security_counter, boot_record, custom_tlv, rom_fixed, max_align, - clear, fix_sig, fix_sig_pubkey, sig_out, user_sha, vector_to_sign, - non_bootable): + endian, encrypt_keylen, encrypt, infile, outfile, dependencies, + load_addr, hex_addr, erased_val, save_enctlv, security_counter, + boot_record, custom_tlv, rom_fixed, max_align, clear, fix_sig, + fix_sig_pubkey, sig_out, user_sha, vector_to_sign, non_bootable): if confirm: # Confirmed but non-padded images don't make much sense, because @@ -456,7 +431,6 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, erased_val=erased_val, save_enctlv=save_enctlv, security_counter=security_counter, max_align=max_align, non_bootable=non_bootable) - compression_tlvs = {} img.load(infile) key = load_key(key) if key else None enckey = load_key(encrypt) if encrypt else None @@ -510,49 +484,10 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, } img.create(key, public_key_format, enckey, dependencies, boot_record, - custom_tlvs, compression_tlvs, int(encrypt_keylen), clear, - baked_signature, pub_key, vector_to_sign, user_sha) - - if compression == "lzma2" : - compressed_img = image.Image(version=decode_version(version), - header_size=header_size, pad_header=pad_header, - pad=pad, confirm=confirm, align=int(align), - slot_size=slot_size, max_sectors=max_sectors, - overwrite_only=overwrite_only, endian=endian, - load_addr=load_addr, rom_fixed=rom_fixed, - erased_val=erased_val, save_enctlv=save_enctlv, - security_counter=security_counter, max_align=max_align) - compression_filters = [ - {"id": lzma.FILTER_LZMA2, "preset": comp_default_preset, - "dict_size": comp_default_dictsize, "lp": comp_default_lp, - "lc": comp_default_lc} - ] - compressed_data = lzma.compress(img.get_infile_data(),filters=compression_filters, - format=lzma.FORMAT_RAW) - uncompressed_size = len(img.get_infile_data()) - compressed_size = len(compressed_data) - print("compressed image size:", compressed_size, - "bytes\noriginal image size:", uncompressed_size, "bytes") - compression_tlvs["DECOMP_SIZE"] = struct.pack( - img.get_struct_endian() + 'L', img.image_size) - compression_tlvs["DECOMP_SHA"] = img.image_hash - compression_tlvs_size = len(compression_tlvs["DECOMP_SIZE"]) - compression_tlvs_size += len(compression_tlvs["DECOMP_SHA"]) - if img.get_signature() is not None and img.get_signature() != "" : - compression_tlvs["DECOMP_SIGNATURE"] = img.get_signature() - compression_tlvs_size += len(compression_tlvs["DECOMP_SIGNATURE"]) - if (compressed_size + compression_tlvs_size) < uncompressed_size: - compression_header = create_lzma2_header( - dictsize = comp_default_dictsize, pb = comp_default_pb, - lc = comp_default_lc, lp = comp_default_lp) - compressed_img.load_compressed(compressed_data, compression_header) - compressed_img.base_addr = img.base_addr - compressed_img.create(key, public_key_format, enckey, - dependencies, boot_record, custom_tlvs, compression_tlvs, - compression, int(encrypt_keylen), clear, baked_signature, - pub_key, vector_to_sign) - img = compressed_img + custom_tlvs, int(encrypt_keylen), clear, baked_signature, + pub_key, vector_to_sign, user_sha) img.save(outfile, hex_addr) + if sig_out is not None: new_signature = img.get_signature() save_signature(sig_out, new_signature) From 6309d08a1e57cd3ab5d10e33072e83b4d8668cf3 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 094/238] Revert "[nrf noup] bootutil: Fix typo in identifier" This reverts commit 763edd653b1b9a5efd643221333e9ea16767da11. --- boot/bootutil/src/image_ed25519.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 40d494bcf..07ac36265 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -118,7 +118,7 @@ bootutil_verify_img(const uint8_t *img, uint32_t size, uint8_t *pubkey; uint8_t *end; - if (slen != EDDSA_SIGNATURE_LENGTH) { + if (slen != EDDSA_SIGNAGURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } From b9ac2e02af7267f012877297049925f1951ea065 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 095/238] Revert "[nrf noup] There is only one SHA supported at once" This reverts commit f79e6db32c897f47f7e630f843bb97063379db2b. --- boot/bootutil/src/image_ed25519.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 07ac36265..984a58302 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -22,15 +22,16 @@ #include "bootutil_priv.h" #include "bootutil/crypto/common.h" -#include "bootutil/crypto/sha.h" -#define EDDSA_SIGNATURE_LENGTH 64 +#define SHA512_LEN 64 +#define SHA256_LEN 32 +#define EDDSA_SIGNAGURE_LENGTH 64 static const uint8_t ed25519_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x65\x70"; #define NUM_ED25519_BYTES 32 extern int ED25519_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[EDDSA_SIGNATURE_LENGTH], + const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], const uint8_t public_key[NUM_ED25519_BYTES]); /* @@ -81,7 +82,8 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, uint8_t *pubkey; uint8_t *end; - if (hlen != IMAGE_HASH_SIZE || slen != EDDSA_SIGNATURE_LENGTH) { + if (!(hlen == SHA512_LEN || hlen == SHA256_LEN) || + slen != EDDSA_SIGNAGURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } @@ -95,7 +97,7 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, goto out; } - rc = ED25519_verify(hash, IMAGE_HASH_SIZE, sig, pubkey); + rc = ED25519_verify(hash, hlen, sig, pubkey); if (rc == 0) { /* if verify returns 0, there was an error. */ From 821fa3e1d1c859ef42c23b42207a174ced69468e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 096/238] Revert "[nrf noup] bootutil: PureEdDSA using ED25519" This reverts commit de524e93b604d54541736875769c851ed6a3ed3e. --- boot/bootutil/include/bootutil/image.h | 3 - boot/bootutil/src/bootutil_priv.h | 3 - boot/bootutil/src/image_ed25519.c | 37 -------- boot/bootutil/src/image_validate.c | 87 ++----------------- boot/zephyr/Kconfig | 29 +------ .../include/mcuboot_config/mcuboot_config.h | 4 - 6 files changed, 8 insertions(+), 155 deletions(-) diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 836712458..9ede800a2 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -102,9 +102,6 @@ struct flash_area; #define IMAGE_TLV_ECDSA_SIG 0x22 /* ECDSA of hash output */ #define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */ #define IMAGE_TLV_ED25519 0x24 /* ed25519 of hash output */ -#define IMAGE_TLV_SIG_PURE 0x25 /* Whatever signature has been selected, it will be used - * as "pure" where signature is verified over entire - * image rather than hash of an image */ #define IMAGE_TLV_ENC_RSA2048 0x30 /* Key encrypted with RSA-OAEP-2048 */ #define IMAGE_TLV_ENC_KW 0x31 /* Key encrypted with AES-KW 128 or 256*/ #define IMAGE_TLV_ENC_EC256 0x32 /* Key encrypted with ECIES-EC256 */ diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h index 68e0595cf..32f996e78 100644 --- a/boot/bootutil/src/bootutil_priv.h +++ b/boot/bootutil/src/bootutil_priv.h @@ -262,9 +262,6 @@ struct boot_loader_state { fih_ret bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, uint8_t key_id); -fih_ret bootutil_verify_img(const uint8_t *img, uint32_t size, - uint8_t *sig, size_t slen, uint8_t key_id); - fih_ret boot_fih_memequal(const void *s1, const void *s2, size_t n); int boot_find_status(int image_index, const struct flash_area **fap); diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 984a58302..c3e8410f1 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -111,41 +111,4 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, FIH_RET(fih_rc); } -fih_ret -bootutil_verify_img(const uint8_t *img, uint32_t size, - uint8_t *sig, size_t slen, uint8_t key_id) -{ - int rc; - FIH_DECLARE(fih_rc, FIH_FAILURE); - uint8_t *pubkey; - uint8_t *end; - - if (slen != EDDSA_SIGNAGURE_LENGTH) { - FIH_SET(fih_rc, FIH_FAILURE); - goto out; - } - - pubkey = (uint8_t *)bootutil_keys[key_id].key; - end = pubkey + *bootutil_keys[key_id].len; - - rc = bootutil_import_key(&pubkey, end); - if (rc) { - FIH_SET(fih_rc, FIH_FAILURE); - goto out; - } - - rc = ED25519_verify(img, size, sig, pubkey); - - if (rc == 0) { - /* if verify returns 0, there was an error. */ - FIH_SET(fih_rc, FIH_FAILURE); - goto out; - } - - FIH_SET(fih_rc, FIH_SUCCESS); -out: - - FIH_RET(fih_rc); -} - #endif /* MCUBOOT_SIGN_ED25519 */ diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 1ba0f7b23..12a9a7188 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -65,7 +65,6 @@ BOOT_LOG_MODULE_DECLARE(mcuboot); #include "bootutil_priv.h" -#ifndef MCUBOOT_SIGN_PURE /* * Compute SHA hash over the image. * (SHA384 if ECDSA-P384 is being used, @@ -185,7 +184,6 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, return 0; } -#endif /* * Currently, we only support being able to verify one type of @@ -372,35 +370,6 @@ bootutil_get_img_security_cnt(struct image_header *hdr, return 0; } -#if defined(MCUBOOT_SIGN_PURE) -/* Returns: - * 0 -- found - * 1 -- not found - * -1 -- failed for some reason - * - * Value of TLV does not matter, presence decides. - */ -static int bootutil_check_for_pure(const struct image_header *hdr, - const struct flash_area *fap) -{ - struct image_tlv_iter it; - uint32_t off; - uint16_t len; - int32_t rc; - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_SIG_PURE, false); - if (rc) { - return rc; - } - - /* Search for the TLV */ - rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); - - return rc; -} -#endif - - #ifndef ALLOW_ROGUE_TLVS /* * The following list of TLVs are the only entries allowed in the unprotected @@ -417,9 +386,6 @@ static const uint16_t allowed_unprot_tlvs[] = { IMAGE_TLV_ECDSA_SIG, IMAGE_TLV_RSA3072_PSS, IMAGE_TLV_ED25519, -#if defined(MCUBOOT_SIGN_PURE) - IMAGE_TLV_SIG_PURE, -#endif IMAGE_TLV_ENC_RSA2048, IMAGE_TLV_ENC_KW, IMAGE_TLV_ENC_EC256, @@ -442,6 +408,7 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, uint32_t off; uint16_t len; uint16_t type; + int image_hash_valid = 0; #ifdef EXPECTED_SIG_TLV FIH_DECLARE(valid_signature, FIH_FAILURE); #ifndef MCUBOOT_BUILTIN_KEY @@ -458,10 +425,7 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, #endif /* EXPECTED_SIG_TLV */ struct image_tlv_iter it; uint8_t buf[SIG_BUF_SIZE]; -#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) - int image_hash_valid = 0; uint8_t hash[IMAGE_HASH_SIZE]; -#endif int rc = 0; FIH_DECLARE(fih_rc, FIH_FAILURE); #ifdef MCUBOOT_HW_ROLLBACK_PROT @@ -530,7 +494,6 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } #endif -#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) rc = bootutil_img_hash(enc_state, image_index, hdr, fap, tmp_buf, tmp_buf_sz, hash, seed, seed_len); if (rc) { @@ -540,15 +503,6 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, if (out_hash) { memcpy(out_hash, hash, IMAGE_HASH_SIZE); } -#endif - -#if defined(MCUBOOT_SIGN_PURE) - /* If Pure type signature is expected then it has to be there */ - rc = bootutil_check_for_pure(hdr, fap); - if (rc != 0) { - goto out; - } -#endif rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false); if (rc) { @@ -592,10 +546,8 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } } #endif - switch(type) { -#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) - case EXPECTED_HASH_TLV: - { + + if (type == EXPECTED_HASH_TLV) { /* Verify the image hash. This must always be present. */ if (len != sizeof(hash)) { rc = -1; @@ -613,12 +565,8 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } image_hash_valid = 1; - break; - } -#endif /* defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) */ #ifdef EXPECTED_KEY_TLV - case EXPECTED_KEY_TLV: - { + } else if (type == EXPECTED_KEY_TLV) { /* * Determine which key we should be checking. */ @@ -643,12 +591,9 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, * The key may not be found, which is acceptable. There * can be multiple signatures, each preceded by a key. */ - break; - } #endif /* EXPECTED_KEY_TLV */ #ifdef EXPECTED_SIG_TLV - case EXPECTED_SIG_TLV: - { + } else if (type == EXPECTED_SIG_TLV) { /* Ignore this signature if it is out of bounds. */ if (key_id < 0 || key_id >= bootutil_key_cnt) { key_id = -1; @@ -662,25 +607,12 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, if (rc) { goto out; } -#ifndef MCUBOOT_SIGN_PURE FIH_CALL(bootutil_verify_sig, valid_signature, hash, sizeof(hash), buf, len, key_id); -#else - /* Directly check signature on the image, by using the mapping of - * a device to memory. The pointer is beginning of image in flash, - * so offset of area, the range is header + image + protected tlvs. - */ - FIH_CALL(bootutil_verify_img, valid_signature, (void *)flash_area_get_off(fap), - hdr->ih_hdr_size + hdr->ih_img_size + hdr->ih_protect_tlv_size, - buf, len, key_id); -#endif key_id = -1; - break; - } #endif /* EXPECTED_SIG_TLV */ #ifdef MCUBOOT_HW_ROLLBACK_PROT - case IMAGE_TLV_SEC_CNT: - { + } else if (type == IMAGE_TLV_SEC_CNT) { /* * Verify the image's security counter. * This must always be present. @@ -715,21 +647,14 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, /* The image's security counter has been successfully verified. */ security_counter_valid = fih_rc; - break; - } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ } } -#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) rc = !image_hash_valid; if (rc) { goto out; } -#elif defined(MCUBOOT_SIGN_PURE) - /* This returns true on EQ, rc is err on non-0 */ - rc = !FIH_EQ(valid_signature, FIH_SUCCESS); -#endif #ifdef EXPECTED_SIG_TLV FIH_SET(fih_rc, valid_signature); #endif diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 70da5d010..acee064d0 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -192,14 +192,6 @@ config BOOT_IMG_HASH_ALG_SHA512 endchoice # BOOT_IMG_HASH_ALG -config BOOT_SIGNATURE_TYPE_PURE_ALLOW - bool - help - Hidden option set by configurations that allow Pure variant, - for example ed25519. The pure variant means that image - signature is calculated over entire image instead of hash - of an image. - choice BOOT_SIGNATURE_TYPE prompt "Signature type" default BOOT_SIGNATURE_TYPE_ED25519 if BOARD_NRF54L15PDK_NRF54L15_CPUAPP @@ -250,32 +242,15 @@ endif config BOOT_SIGNATURE_TYPE_ED25519 bool "Edwards curve digital signatures using ed25519" - select BOOT_ENCRYPTION_SUPPORT if !BOOT_SIGNATURE_TYPE_PURE - select BOOT_IMG_HASH_ALG_SHA256_ALLOW if !BOOT_SIGNATURE_TYPE_PURE - # The SHA is used only for key hashing, not for images. + select BOOT_ENCRYPTION_SUPPORT + select BOOT_IMG_HASH_ALG_SHA256_ALLOW select BOOT_IMG_HASH_ALG_SHA512_ALLOW - select BOOT_SIGNATURE_TYPE_PURE_ALLOW help This is ed25519 signature calculated over SHA512 of SHA256 of application image; that is not completely correct approach as the SHA512 should be rather directly calculated over an image. - Select BOOT_SIGNATURE_TYPE_PURE to have a PureEdDSA calculating image - signature directly on image, rather than hash of the image. if BOOT_SIGNATURE_TYPE_ED25519 - -config BOOT_SIGNATURE_TYPE_PURE - bool "Use Pure signature of image" - depends on BOOT_SIGNATURE_TYPE_PURE_ALLOW - help - The Pure signature is calculated directly over image rather than - hash of an image. - This is more secure signature, specifically if hardware can do the - verification without need to share key. - Note that this requires that all slots for which signature is to be - verified need to be accessible through memory address space that - cryptography can access. - choice BOOT_ED25519_IMPLEMENTATION prompt "Ecdsa implementation" default BOOT_ED25519_TINYCRYPT diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index f04be2434..4f31a623e 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -147,10 +147,6 @@ #define MCUBOOT_HASH_STORAGE_DIRECTLY #endif -#ifdef CONFIG_BOOT_SIGNATURE_TYPE_PURE -#define MCUBOOT_SIGN_PURE -#endif - #ifdef CONFIG_BOOT_BOOTSTRAP #define MCUBOOT_BOOTSTRAP 1 #endif From 979469c793924b811ec600607a5154b3c3e264bb Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 097/238] Revert "[nrf noup] bootutil: Enable hash calculation directly on storage" This reverts commit e1591c0ca0cfb89cb643fe7b6bede40a25596c18. --- boot/bootutil/src/image_validate.c | 15 +++------------ boot/zephyr/Kconfig | 16 ---------------- .../include/mcuboot_config/mcuboot_config.h | 7 ------- 3 files changed, 3 insertions(+), 35 deletions(-) diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 12a9a7188..a6155f7b0 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -77,15 +77,13 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, uint8_t *seed, int seed_len) { bootutil_sha_context sha_ctx; + uint32_t blk_sz; uint32_t size; uint16_t hdr_size; + uint32_t off; + int rc; uint32_t blk_off; uint32_t tlv_off; -#if !defined(MCUBOOT_HASH_STORAGE_DIRECTLY) - int rc; - uint32_t off; - uint32_t blk_sz; -#endif #if (BOOT_IMAGE_NUMBER == 1) || !defined(MCUBOOT_ENC_IMAGES) || \ defined(MCUBOOT_RAM_LOAD) @@ -128,12 +126,6 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, /* If protected TLVs are present they are also hashed. */ size += hdr->ih_protect_tlv_size; -#ifdef MCUBOOT_HASH_STORAGE_DIRECTLY - /* No chunk loading, storage is mapped to address space and can - * be directly given to hashing function. - */ - bootutil_sha_update(&sha_ctx, (void *)flash_area_get_off(fap), size); -#else /* MCUBOOT_HASH_STORAGE_DIRECTLY */ #ifdef MCUBOOT_RAM_LOAD bootutil_sha_update(&sha_ctx, (void*)(IMAGE_RAM_BASE + hdr->ih_load_addr), @@ -178,7 +170,6 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, bootutil_sha_update(&sha_ctx, tmp_buf, blk_sz); } #endif /* MCUBOOT_RAM_LOAD */ -#endif /* MCUBOOT_HASH_STORAGE_DIRECTLY */ bootutil_sha_finish(&sha_ctx, hash_result); bootutil_sha_drop(&sha_ctx); diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index acee064d0..859d21454 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -146,22 +146,6 @@ config BOOT_IMG_HASH_ALG_SHA512_ALLOW help Hidden option set by configurations that allow SHA512 -config BOOT_IMG_HASH_DIRECTLY_ON_STORAGE - bool "Hash calculation functions access storage through address space" - depends on !BOOT_ENCRYPT_IMAGE - help - When possible to map storage device, at least for read operations, - to address space or RAM area, enabling this option allows hash - calculation functions to directly access the storage through that address - space or using its own DMA. This reduces flash read overhead done - by the MCUboot. - Notes: - - not supported when encrypted images are in use, because calculating - SHA requires image to be decrypted first, which is done to RAM. - - currently only supported on internal storage of devices; this - option will not work with devices that use external storage for - either of image slots. - choice BOOT_IMG_HASH_ALG prompt "Selected image hash algorithm" default BOOT_IMG_HASH_ALG_SHA256 if BOOT_IMG_HASH_ALG_SHA256_ALLOW diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 4f31a623e..9d58436d2 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -140,13 +140,6 @@ #define MCUBOOT_DECOMPRESS_IMAGES #endif -/* Invoke hashing functions directly on storage. This requires for device - * to be able to map storage to address space or RAM. - */ -#ifdef CONFIG_BOOT_IMG_HASH_DIRECTLY_ON_STORAGE -#define MCUBOOT_HASH_STORAGE_DIRECTLY -#endif - #ifdef CONFIG_BOOT_BOOTSTRAP #define MCUBOOT_BOOTSTRAP 1 #endif From 5ed9f8acc2f23155a7158376b0b66b383b15ef81 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 098/238] Revert "[nrf noup] bootutil: Provide support for SHA512 with ED25519" This reverts commit 273c10638d3714bdf675d2be44cf6c8957f6249c. --- boot/zephyr/Kconfig | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 859d21454..264c08241 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -79,7 +79,7 @@ config BOOT_PSA_IMG_HASH_ALG_SHA256_DEPENDENCIES config BOOT_ED25519_PSA_DEPENDENCIES bool - select PSA_WANT_ALG_SHA_256 if BOOT_IMG_HASH_ALG_SHA256 + select PSA_WANT_ALG_SHA_256 select PSA_WANT_ALG_SHA_512 select PSA_WANT_ALG_PURE_EDDSA select PSA_WANT_ECC_TWISTED_EDWARDS_255 @@ -228,11 +228,6 @@ config BOOT_SIGNATURE_TYPE_ED25519 bool "Edwards curve digital signatures using ed25519" select BOOT_ENCRYPTION_SUPPORT select BOOT_IMG_HASH_ALG_SHA256_ALLOW - select BOOT_IMG_HASH_ALG_SHA512_ALLOW - help - This is ed25519 signature calculated over SHA512 of SHA256 of application - image; that is not completely correct approach as the SHA512 should be - rather directly calculated over an image. if BOOT_SIGNATURE_TYPE_ED25519 choice BOOT_ED25519_IMPLEMENTATION From 161a140a21c5b0caf78658cee485d0b9fc94095b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 099/238] Revert "[nrf noup] Exclude PSA source on non-PSA crypto configuration" This reverts commit 5721744229fe352fddd1e85aaf4b85acfabe166e. --- boot/zephyr/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 8b877f32e..8a2c97ead 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -108,7 +108,7 @@ zephyr_library_sources( ${BOOT_DIR}/bootutil/src/fault_injection_hardening.c ) -if(DEFINED CONFIG_BOOT_ENCRYPT_X25519 AND DEFINED CONFIG_BOOT_ED25519_PSA) +if(DEFINED CONFIG_BOOT_ENCRYPT_X25519) zephyr_library_sources(${BOOT_DIR}/bootutil/src/encrypted_psa.c) endif() From 54397f609334575a8ccd5dd2f8937dd323ca282c Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 100/238] Revert "[nrf noup] PSA implementation of x25519 and ed25519 verification" This reverts commit 5f95fecfa27e5b9924a91c69bca023e605fe751e. --- .../include/bootutil/crypto/aes_ctr.h | 38 +- boot/bootutil/src/ed25519_psa.c | 71 --- boot/bootutil/src/encrypted.c | 114 +++-- boot/bootutil/src/encrypted_psa.c | 453 ------------------ boot/bootutil/src/image_ed25519.c | 18 +- 5 files changed, 60 insertions(+), 634 deletions(-) delete mode 100644 boot/bootutil/src/ed25519_psa.c delete mode 100644 boot/bootutil/src/encrypted_psa.c diff --git a/boot/bootutil/include/bootutil/crypto/aes_ctr.h b/boot/bootutil/include/bootutil/crypto/aes_ctr.h index fd2416176..e69b0372f 100644 --- a/boot/bootutil/include/bootutil/crypto/aes_ctr.h +++ b/boot/bootutil/include/bootutil/crypto/aes_ctr.h @@ -15,8 +15,8 @@ #include "mcuboot_config/mcuboot_config.h" #if (defined(MCUBOOT_USE_MBED_TLS) + \ - defined(MCUBOOT_USE_TINYCRYPT) + defined(MCUBOOT_USE_PSA_CRYPTO)) != 1 - #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT or PSA" + defined(MCUBOOT_USE_TINYCRYPT)) != 1 + #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT" #endif #if defined(MCUBOOT_USE_MBED_TLS) @@ -38,46 +38,12 @@ #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE TC_AES_BLOCK_SIZE #endif /* MCUBOOT_USE_TINYCRYPT */ - -#if defined(MCUBOOT_USE_PSA_CRYPTO) - #include - #include "bootutil/enc_key_public.h" - #define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE BOOT_ENC_KEY_SIZE - #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16) -#endif - #include #ifdef __cplusplus extern "C" { #endif -#if defined(MCUBOOT_USE_PSA_CRYPTO) -typedef struct { - /* Fixme: This should not be, here, psa_key_id should be passed */ - uint8_t key[BOOT_ENC_KEY_SIZE]; -} bootutil_aes_ctr_context; - -void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx); - -static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx) -{ - memset(ctx, 0, sizeof(ctx)); -} - -static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k) -{ - memcpy(ctx->key, k, sizeof(ctx->key)); - - return 0; -} - -int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, - const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c); -int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, - const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m); -#endif - #if defined(MCUBOOT_USE_MBED_TLS) typedef mbedtls_aes_context bootutil_aes_ctr_context; static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx) diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c deleted file mode 100644 index 3d7274307..000000000 --- a/boot/bootutil/src/ed25519_psa.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ -#include -#include -#include - -#include -#include "bootutil/bootutil_log.h" - -#include -#include - -BOOT_LOG_MODULE_DECLARE(ed25519_psa); - -#define SHA512_DIGEST_LENGTH 64 -#define EDDSA_KEY_LENGTH 32 -#define EDDSA_SIGNAGURE_LENGTH 64 - -int ED25519_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], - const uint8_t public_key[EDDSA_KEY_LENGTH]) -{ - /* Set to any error */ - psa_status_t status = PSA_ERROR_BAD_STATE; - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t kid; - int ret = 0; /* Fail by default */ - - /* Initialize PSA Crypto */ - status = psa_crypto_init(); - if (status != PSA_SUCCESS) { - BOOT_LOG_ERR("PSA crypto init failed %d\n", status); - return 0; - } - - status = PSA_ERROR_BAD_STATE; - - psa_set_key_type(&key_attr, - PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS)); - psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE); - psa_set_key_algorithm(&key_attr, PSA_ALG_PURE_EDDSA); - - status = psa_import_key(&key_attr, public_key, EDDSA_KEY_LENGTH, &kid); - if (status != PSA_SUCCESS) { - BOOT_LOG_ERR("ED25519 key import failed %d", status); - return 0; - } - - status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, message_len, - signature, EDDSA_SIGNAGURE_LENGTH); - if (status != PSA_SUCCESS) { - BOOT_LOG_ERR("ED25519 signature verification failed %d", status); - ret = 0; - /* Pass through to destroy key */ - } else { - ret = 1; - /* Pass through to destroy key */ - } - - status = psa_destroy_key(kid); - - if (status != PSA_SUCCESS) { - /* Just for logging */ - BOOT_LOG_WRN("Failed to destroy key %d", status); - } - - return ret; -} diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index e794fe66c..b48f859f6 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -25,7 +25,6 @@ #include "bootutil/crypto/ecdh_p256.h" #endif -#if !defined(MCUBOOT_USE_PSA_CRYPTO) #if defined(MCUBOOT_ENCRYPT_X25519) #include "bootutil/crypto/ecdh_x25519.h" #endif @@ -36,7 +35,6 @@ #include "mbedtls/oid.h" #include "mbedtls/asn1.h" #endif -#endif #include "bootutil/image.h" #include "bootutil/enc_key.h" @@ -45,30 +43,6 @@ #include "bootutil_priv.h" -#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE - -#if defined(MCUBOOT_ENCRYPT_RSA) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048 -#elif defined(MCUBOOT_ENCRYPT_KW) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW -#elif defined(MCUBOOT_ENCRYPT_EC256) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256 -# define EC_PUBK_INDEX (0) -# define EC_TAG_INDEX (65) -# define EC_CIPHERKEY_INDEX (65 + 32) -_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, - "Please fix ECIES-P256 component indexes"); -#elif defined(MCUBOOT_ENCRYPT_X25519) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519 -# define EC_PUBK_INDEX (0) -# define EC_TAG_INDEX (32) -# define EC_CIPHERKEY_INDEX (32 + 32) -_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, - "Please fix ECIES-X25519 component indexes"); -#endif - -/* NOUP Fixme: */ -#if !defined(CONFIG_BOOT_ED25519_PSA) #if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519) #if defined(_compare) static inline int bootutil_constant_time_compare(const uint8_t *a, const uint8_t *b, size_t size) @@ -362,6 +336,60 @@ hkdf(uint8_t *ikm, uint16_t ikm_len, uint8_t *info, uint16_t info_len, } #endif +int +boot_enc_init(struct enc_key_data *enc_state, uint8_t slot) +{ + bootutil_aes_ctr_init(&enc_state[slot].aes_ctr); + return 0; +} + +int +boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot) +{ + bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr); + enc_state[slot].valid = 0; + return 0; +} + +int +boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, + const struct boot_status *bs) +{ + int rc; + + rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]); + if (rc != 0) { + boot_enc_drop(enc_state, slot); + return -1; + } + + enc_state[slot].valid = 1; + + return 0; +} + +#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE + +#if defined(MCUBOOT_ENCRYPT_RSA) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048 +#elif defined(MCUBOOT_ENCRYPT_KW) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW +#elif defined(MCUBOOT_ENCRYPT_EC256) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256 +# define EC_PUBK_INDEX (0) +# define EC_TAG_INDEX (65) +# define EC_CIPHERKEY_INDEX (65 + 32) +_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, + "Please fix ECIES-P256 component indexes"); +#elif defined(MCUBOOT_ENCRYPT_X25519) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519 +# define EC_PUBK_INDEX (0) +# define EC_TAG_INDEX (32) +# define EC_CIPHERKEY_INDEX (32 + 32) +_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, + "Please fix ECIES-X25519 component indexes"); +#endif + #if ( (defined(MCUBOOT_ENCRYPT_RSA) && defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_PSA_CRYPTO)) || \ (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS)) ) #if MBEDTLS_VERSION_NUMBER >= 0x03000000 @@ -574,7 +602,6 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey) return rc; } -#endif /* CONFIG_BOOT_ED25519_PSA */ /* * Load encryption key. @@ -629,39 +656,6 @@ boot_enc_load(struct enc_key_data *enc_state, int slot, return boot_decrypt_key(buf, bs->enckey[slot]); } -int -boot_enc_init(struct enc_key_data *enc_state, uint8_t slot) -{ - bootutil_aes_ctr_init(&enc_state[slot].aes_ctr); - return 0; -} - -int -boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot) -{ - bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr); - enc_state[slot].valid = 0; - return 0; -} - -int -boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, - const struct boot_status *bs) -{ - int rc; - - rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]); - if (rc != 0) { - boot_enc_drop(enc_state, slot); - return -1; - } - - enc_state[slot].valid = 1; - - return 0; -} - - bool boot_enc_valid(struct enc_key_data *enc_state, int slot) { diff --git a/boot/bootutil/src/encrypted_psa.c b/boot/bootutil/src/encrypted_psa.c deleted file mode 100644 index 927ce2d6b..000000000 --- a/boot/bootutil/src/encrypted_psa.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#include "mcuboot_config/mcuboot_config.h" - -#include -#include -#include - -/* We are not really using the MBEDTLS but need the ASN.1 parsing functions */ -#define MBEDTLS_ASN1_PARSE_C - -#include "bootutil/crypto/sha.h" -#include "mbedtls/oid.h" -#include "mbedtls/asn1.h" - -#include "bootutil/image.h" -#include "bootutil/enc_key.h" -#include "bootutil/sign_key.h" -#include "bootutil/crypto/common.h" - -#include "bootutil_priv.h" -#include "bootutil/bootutil_log.h" - -BOOT_LOG_MODULE_DECLARE(mcuboot_psa_enc); - -#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE -#define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519 -#define EC_PUBK_INDEX (0) -#define EC_TAG_INDEX (32) -#define EC_CIPHERKEY_INDEX (32 + 32) -_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, - "Please fix ECIES-X25519 component indexes"); - -#define X25519_OID "\x6e" -static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG \ - MBEDTLS_OID_ORG_GOV X25519_OID; - -#define SHARED_KEY_LEN 32 -#define PRIV_KEY_LEN 32 - -/* Fixme: This duplicates code from encrypted.c and depends on mbedtls */ -static int -parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key) -{ - size_t len; - int version; - mbedtls_asn1_buf alg; - mbedtls_asn1_buf param; - - if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE) != 0) { - return -1; - } - - if (*p + len != end) { - return -2; - } - - version = 0; - if (mbedtls_asn1_get_int(p, end, &version) || version != 0) { - return -3; - } - - if (mbedtls_asn1_get_alg(p, end, &alg, ¶m) != 0) { - return -4; - } - - if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || - memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { - return -5; - } - - if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) { - return -6; - } - - if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) { - return -7; - } - - if (len != PRIV_KEY_LEN) { - return -8; - } - - memcpy(private_key, *p, PRIV_KEY_LEN); - return 0; -} - -void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx) -{ - psa_status_t psa_ret = psa_crypto_init(); - - (void)ctx; - - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES init PSA crypto init failed %d", psa_ret); - assert(0); - } -} - -#if defined(MCUBOOT_ENC_IMAGES) -/* - * Decrypt an encryption key TLV. - * - * @param buf An encryption TLV read from flash (build time fixed length) - * @param enckey An AES-128 or AES-256 key sized buffer to store to plain key. - */ -int -boot_decrypt_key(const uint8_t *buf, uint8_t *enckey) -{ - uint8_t derived_key[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE]; - uint8_t *cp; - uint8_t *cpend; - uint8_t private_key[PRIV_KEY_LEN]; - size_t len; - psa_status_t psa_ret = PSA_ERROR_BAD_STATE; - psa_status_t psa_cleanup_ret = PSA_ERROR_BAD_STATE; - psa_key_id_t kid; - psa_key_attributes_t kattr = PSA_KEY_ATTRIBUTES_INIT; - psa_key_derivation_operation_t key_do = PSA_KEY_DERIVATION_OPERATION_INIT; - psa_algorithm_t key_do_alg; - int rc = -1; - - cp = (uint8_t *)bootutil_enc_key.key; - cpend = cp + *bootutil_enc_key.len; - - /* The psa_cipher_decrypt needs initialization vector of proper length at - * the beginning of the input buffer. - */ - uint8_t iv_and_key[PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR) + - BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE]; - - psa_ret = psa_crypto_init(); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES crypto init failed %d", psa_ret); - return -1; - } - - /* - * Load the stored X25519 decryption private key - */ - rc = parse_x25519_enckey(&cp, cpend, private_key); - if (rc) { - return rc; - } - - psa_set_key_type(&kattr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY)); - psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&kattr, PSA_ALG_ECDH); - - psa_ret = psa_import_key(&kattr, private_key, sizeof(private_key), &kid); - memset(private_key, 0, sizeof(private_key)); - psa_reset_key_attributes(&kattr); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("Built-in key import failed %d", psa_ret); - return -1; - } - - key_do_alg = PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)); - - psa_ret = psa_key_derivation_setup(&key_do, key_do_alg); - if (psa_ret != PSA_SUCCESS) { - psa_cleanup_ret = psa_destroy_key(kid); - if (psa_cleanup_ret != PSA_SUCCESS) { - BOOT_LOG_WRN("Built-in key destruction failed %d", psa_cleanup_ret); - } - BOOT_LOG_ERR("Key derivation setup failed %d", psa_ret); - return -1; - } - - /* Note: PSA 1.1.2 does not have psa_key_agreement that would be useful here - * as it could just add the derived key to the storage and return key id. - * Instead, we have to use the code below to generate derived key and put it - * into storage, to obtain the key id we can then use with psa_mac_* functions. - */ - psa_ret = psa_key_derivation_key_agreement(&key_do, PSA_KEY_DERIVATION_INPUT_SECRET, - kid, &buf[EC_PUBK_INDEX], - BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE); - psa_cleanup_ret = psa_destroy_key(kid); - if (psa_cleanup_ret != PSA_SUCCESS) { - BOOT_LOG_WRN("Built-in key destruction failed %d", psa_cleanup_ret); - } - if (psa_ret != PSA_SUCCESS) { - psa_cleanup_ret = psa_key_derivation_abort(&key_do); - if (psa_cleanup_ret != PSA_SUCCESS) { - BOOT_LOG_WRN("Key derivation abort failed %d", psa_ret); - } - - BOOT_LOG_ERR("Key derivation failed %d", psa_ret); - return -1; - } - - /* Only info, no salt */ - psa_ret = psa_key_derivation_input_bytes(&key_do, PSA_KEY_DERIVATION_INPUT_INFO, - "MCUBoot_ECIES_v1", 16); - if (psa_ret != PSA_SUCCESS) { - psa_cleanup_ret = psa_key_derivation_abort(&key_do); - if (psa_cleanup_ret != PSA_SUCCESS) { - BOOT_LOG_WRN("Key derivation abort failed %d", psa_ret); - } - BOOT_LOG_ERR("Key derivation failed %d", psa_ret); - return -1; - } - - len = BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE; - psa_ret = psa_key_derivation_output_bytes(&key_do, derived_key, len); - psa_cleanup_ret = psa_key_derivation_abort(&key_do); - if (psa_cleanup_ret != PSA_SUCCESS) { - BOOT_LOG_WRN("Key derivation cleanup failed %d", psa_ret); - } - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("Key derivation failed %d", psa_ret); - return -1; - } - - /* The derived key consists of BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE bytes - * followed by BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE bytes. Both parts will - * be imported at the point where needed and discarded immediately after. - */ - psa_set_key_type(&kattr, PSA_KEY_TYPE_HMAC); - psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_VERIFY_MESSAGE); - psa_set_key_algorithm(&kattr, PSA_ALG_HMAC(PSA_ALG_SHA_256)); - - /* Import the MAC tag key part of derived key, that is the part that starts - * after BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE and has length of - * BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE bytes. - */ - psa_ret = psa_import_key(&kattr, - &derived_key[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE], - BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE, &kid); - psa_reset_key_attributes(&kattr); - if (psa_ret != PSA_SUCCESS) { - memset(derived_key, 0, sizeof(derived_key)); - BOOT_LOG_ERR("MAC key import failed %d", psa_ret); - return -1; - } - - /* Verify the MAC tag of the random encryption key */ - psa_ret = psa_mac_verify(kid, PSA_ALG_HMAC(PSA_ALG_SHA_256), - &buf[EC_CIPHERKEY_INDEX], BOOT_ENC_KEY_SIZE, - &buf[EC_TAG_INDEX], - BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE); - psa_cleanup_ret = psa_destroy_key(kid); - if (psa_cleanup_ret != PSA_SUCCESS) { - BOOT_LOG_WRN("MAC key destruction failed %d", psa_cleanup_ret); - } - if (psa_ret != PSA_SUCCESS) { - memset(derived_key, 0, sizeof(derived_key)); - BOOT_LOG_ERR("MAC verification failed %d", psa_ret); - return -1; - } - - /* The derived key is used in AES decryption of random key */ - psa_set_key_type(&kattr, PSA_KEY_TYPE_AES); - psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_DECRYPT); - psa_set_key_algorithm(&kattr, PSA_ALG_CTR); - - /* Import the AES partition of derived key, the first 16 bytes */ - psa_ret = psa_import_key(&kattr, &derived_key[0], - BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE, &kid); - memset(derived_key, 0, sizeof(derived_key)); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES key import failed %d", psa_ret); - return -1; - } - - /* Decrypt the random AES encryption key with AES and the key obtained - * at derivation. */ - memset(&iv_and_key[0], 0, PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR)); - memcpy(&iv_and_key[PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR)], - &buf[EC_CIPHERKEY_INDEX], - sizeof(iv_and_key) - PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR)); - - len = 0; - psa_ret = psa_cipher_decrypt(kid, PSA_ALG_CTR, iv_and_key, sizeof(iv_and_key), - enckey, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE, &len); - memset(iv_and_key, 0, sizeof(iv_and_key)); - psa_cleanup_ret = psa_destroy_key(kid); - if (psa_cleanup_ret != PSA_SUCCESS) { - BOOT_LOG_WRN("AES key destruction failed %d", psa_cleanup_ret); - } - if (psa_ret != PSA_SUCCESS || len != BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE) { - memset(enckey, 0, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE); - BOOT_LOG_ERR("Random key decryption failed %d", psa_ret); - return -1; - } - - return 0; -} - -int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, - const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c) -{ - int ret = 0; - psa_status_t psa_ret = PSA_ERROR_BAD_STATE; - psa_key_attributes_t kattr = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t kid; - psa_cipher_operation_t psa_op; - size_t elen = 0; /* Decrypted length */ - - /* Fixme: calling psa_crypto_init multiple times is not a problem, - * yet the code here is only present because there is not general - * crypto init. */ - psa_ret = psa_crypto_init(); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("PSA crypto init failed %d", psa_ret); - ret = -1; - goto gone; - } - - psa_op = psa_cipher_operation_init(); - - /* Fixme: Import should happen when key is decrypted, but due to lack - * of key destruction there is no way to destroy key stored by - * psa other way than here. */ - psa_set_key_type(&kattr, PSA_KEY_TYPE_AES); - psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_ENCRYPT); - psa_set_key_algorithm(&kattr, PSA_ALG_CTR); - - psa_ret = psa_import_key(&kattr, ctx->key, BOOT_ENC_KEY_SIZE, &kid); - psa_reset_key_attributes(&kattr); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES enc import key failed %d", psa_ret); - ret = -1; - goto gone; - } - - /* This could be done with psa_cipher_decrypt one-shot operation, but - * multi-part operation is used to avoid re-allocating input buffer - * to account for IV in front of data. - */ - psa_ret = psa_cipher_encrypt_setup(&psa_op, kid, PSA_ALG_CTR); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES enc setup failed %d", psa_ret); - ret = -1; - goto gone_with_key; - } - - /* Fixme: hardcoded counter size, but it is hardcoded everywhere */ - psa_ret = psa_cipher_set_iv(&psa_op, counter, 16); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES enc IV set failed %d", psa_ret); - ret = -1; - goto gone_after_setup; - } - - psa_ret = psa_cipher_update(&psa_op, m, mlen, c, mlen, &elen); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES enc encryption failed %d", psa_ret); - ret = -1; - goto gone_after_setup; - } - -gone_after_setup: - psa_ret = psa_cipher_abort(&psa_op); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_WRN("AES enc cipher abort failed %d", psa_ret); - /* Intentionally not changing the ret */ - } -gone_with_key: - /* Fixme: Should be removed once key is shared by id */ - psa_ret = psa_destroy_key(kid); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_WRN("AES enc destroy key failed %d", psa_ret); - /* Intentionally not changing the ret */ - } -gone: - return ret; -} - -int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, - const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m) -{ - int ret = 0; - psa_status_t psa_ret = PSA_ERROR_BAD_STATE; - psa_key_attributes_t kattr = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t kid; - psa_cipher_operation_t psa_op; - size_t dlen = 0; /* Decrypted length */ - - /* Fixme: the init should already happen before calling the function, but - * somehow it does not, for example when recovering in swap. - */ - psa_ret = psa_crypto_init(); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("PSA crypto init failed %d", psa_ret); - ret = -1; - goto gone; - } - - psa_op = psa_cipher_operation_init(); - - /* Fixme: Import should happen when key is decrypted, but due to lack - * of key destruction there is no way to destroy key stored by - * psa other way than here. */ - psa_set_key_type(&kattr, PSA_KEY_TYPE_AES); - psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_DECRYPT); - psa_set_key_algorithm(&kattr, PSA_ALG_CTR); - - psa_ret = psa_import_key(&kattr, ctx->key, BOOT_ENC_KEY_SIZE, &kid); - psa_reset_key_attributes(&kattr); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES dec import key failed %d", psa_ret); - ret = -1; - goto gone; - } - - /* This could be done with psa_cipher_decrypt one-shot operation, but - * multi-part operation is used to avoid re-allocating input buffer - * to account for IV in front of data. - */ - psa_ret = psa_cipher_decrypt_setup(&psa_op, kid, PSA_ALG_CTR); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES dec setup failed %d", psa_ret); - ret = -1; - goto gone_with_key; - } - - /* Fixme: hardcoded counter size, but it is hardcoded everywhere */ - psa_ret = psa_cipher_set_iv(&psa_op, counter, 16); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES dec IV set failed %d", psa_ret); - ret = -1; - goto gone_after_setup; - } - - psa_ret = psa_cipher_update(&psa_op, c, clen, m, clen, &dlen); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES dec decryption failed %d", psa_ret); - ret = -1; - goto gone_after_setup; - } - -gone_after_setup: - psa_ret = psa_cipher_abort(&psa_op); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_WRN("PSA dec abort failed %d", psa_ret); - /* Intentionally not changing the ret */ - } -gone_with_key: - psa_ret = psa_destroy_key(kid); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_WRN("PSA dec key failed %d", psa_ret); - /* Intentionally not changing the ret */ - } -gone: - return ret; -} -#endif /* defined(MCUBOOT_ENC_IMAGES) */ diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index c3e8410f1..7a597d4c0 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -9,11 +9,6 @@ #include "mcuboot_config/mcuboot_config.h" -#if defined(CONFIG_NRF_SECURITY) -/* We are not really using the MBEDTLS but need the ASN.1 parsing funcitons */ -#define MBEDTLS_ASN1_PARSE_C -#endif - #ifdef MCUBOOT_SIGN_ED25519 #include "bootutil/sign_key.h" @@ -23,16 +18,12 @@ #include "bootutil_priv.h" #include "bootutil/crypto/common.h" -#define SHA512_LEN 64 -#define SHA256_LEN 32 -#define EDDSA_SIGNAGURE_LENGTH 64 - static const uint8_t ed25519_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x65\x70"; #define NUM_ED25519_BYTES 32 extern int ED25519_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], - const uint8_t public_key[NUM_ED25519_BYTES]); + const uint8_t signature[64], + const uint8_t public_key[32]); /* * Parse the public key used for signing. @@ -82,8 +73,7 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, uint8_t *pubkey; uint8_t *end; - if (!(hlen == SHA512_LEN || hlen == SHA256_LEN) || - slen != EDDSA_SIGNAGURE_LENGTH) { + if (hlen != 32 || slen != 64) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } @@ -97,7 +87,7 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, goto out; } - rc = ED25519_verify(hash, hlen, sig, pubkey); + rc = ED25519_verify(hash, 32, sig, pubkey); if (rc == 0) { /* if verify returns 0, there was an error. */ From 65979ceb3a8629a44a006367e2686ec6352428e3 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 101/238] Revert "[nrf noup] PSA configuration required changes" This reverts commit be3637e0404f3e3b81eee75903f70532e3c6914f. --- boot/bootutil/zephyr/CMakeLists.txt | 14 ++--- boot/zephyr/CMakeLists.txt | 39 ++++-------- boot/zephyr/Kconfig | 72 +---------------------- boot/zephyr/include/mcuboot-mbedtls-cfg.h | 2 +- 4 files changed, 16 insertions(+), 111 deletions(-) diff --git a/boot/bootutil/zephyr/CMakeLists.txt b/boot/bootutil/zephyr/CMakeLists.txt index d5364d025..72a6a8638 100644 --- a/boot/bootutil/zephyr/CMakeLists.txt +++ b/boot/bootutil/zephyr/CMakeLists.txt @@ -29,18 +29,12 @@ zephyr_library_link_libraries(MCUBOOT_BOOTUTIL) target_link_libraries(MCUBOOT_BOOTUTIL INTERFACE zephyr_interface) if(CONFIG_BOOT_USE_TINYCRYPT) - target_include_directories(MCUBOOT_BOOTUTIL INTERFACE - ../../../ext/tinycrypt/lib/include - ) -endif() - -if(CONFIG_BOOT_USE_PSA_CRYPTO) - target_include_directories(MCUBOOT_BOOTUTIL INTERFACE - ${ZEPHYR_MBEDTLS_MODULE_DIR}/include - ) +target_include_directories(MCUBOOT_BOOTUTIL INTERFACE + ../../../ext/tinycrypt/lib/include +) endif() -if(CONFIG_BOOT_USE_MBEDTLS OR CONFIG_BOOT_USE_PSA_CRYPTO AND NOT CONFIG_PSA_CORE_OBERON) +if(CONFIG_BOOT_USE_MBEDTLS) zephyr_link_libraries(mbedTLS) endif() endif() diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 8a2c97ead..c26633d11 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -51,12 +51,6 @@ if(EXISTS targets/${BOARD}.h) zephyr_library_compile_definitions(MCUBOOT_TARGET_CONFIG="${BOARD}.h") endif() -if(DEFINED CONFIG_MBEDTLS) - zephyr_library_include_directories( - ${ZEPHYR_MBEDTLS_MODULE_DIR}/include - ) -endif() - # Zephyr port-specific sources. zephyr_library_sources( main.c @@ -108,10 +102,6 @@ zephyr_library_sources( ${BOOT_DIR}/bootutil/src/fault_injection_hardening.c ) -if(DEFINED CONFIG_BOOT_ENCRYPT_X25519) - zephyr_library_sources(${BOOT_DIR}/bootutil/src/encrypted_psa.c) -endif() - if(DEFINED CONFIG_MEASURED_BOOT OR DEFINED CONFIG_BOOT_SHARE_DATA) zephyr_library_sources( ${BOOT_DIR}/bootutil/src/boot_record.c @@ -240,28 +230,19 @@ elseif(CONFIG_BOOT_SIGNATURE_TYPE_ED25519 OR CONFIG_BOOT_ENCRYPT_X25519) ${FIAT_DIR}/include/ ) - if(NOT CONFIG_BOOT_ED25519_PSA) - zephyr_library_sources( - ${FIAT_DIR}/src/curve25519.c - ) - else() - zephyr_library_sources( - ${MBEDTLS_ASN1_DIR}/src/asn1parse.c - ${BOOT_DIR}/bootutil/src/ed25519_psa.c - ) - endif() + zephyr_library_sources( + ${FIAT_DIR}/src/curve25519.c + ) endif() -if(NOT CONFIG_BOOT_ED25519_PSA) - if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519) - zephyr_library_sources( - ${TINYCRYPT_DIR}/source/aes_encrypt.c - ${TINYCRYPT_DIR}/source/aes_decrypt.c - ${TINYCRYPT_DIR}/source/ctr_mode.c - ${TINYCRYPT_DIR}/source/hmac.c - ${TINYCRYPT_DIR}/source/ecc_dh.c +if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519) + zephyr_library_sources( + ${TINYCRYPT_DIR}/source/aes_encrypt.c + ${TINYCRYPT_DIR}/source/aes_decrypt.c + ${TINYCRYPT_DIR}/source/ctr_mode.c + ${TINYCRYPT_DIR}/source/hmac.c + ${TINYCRYPT_DIR}/source/ecc_dh.c ) - endif() endif() if(CONFIG_BOOT_ENCRYPT_EC256) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 264c08241..8b35ab18c 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -29,9 +29,7 @@ config BOOT_USE_MBEDTLS config BOOT_USE_PSA_CRYPTO bool - default y if NRF_SECURITY - # This is counter intuitive but that is how PSA heap is enabled. - select MBEDTLS_ENABLE_HEAP + # Hidden option help Hidden option set if using PSA crypt for cryptography functionality @@ -68,58 +66,6 @@ config NRF_CC310_BL bool default n -if BOOT_USE_PSA_CRYPTO - -config BOOT_PSA_IMG_HASH_ALG_SHA256_DEPENDENCIES - bool - default y if BOOT_IMG_HASH_ALG_SHA256 - select PSA_WANT_ALG_SHA_256 - help - Dependencies for hashing with SHA256 - -config BOOT_ED25519_PSA_DEPENDENCIES - bool - select PSA_WANT_ALG_SHA_256 - select PSA_WANT_ALG_SHA_512 - select PSA_WANT_ALG_PURE_EDDSA - select PSA_WANT_ECC_TWISTED_EDWARDS_255 - select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT - help - Dependencies for ed25519 signature - -if BOOT_ENCRYPT_IMAGE - -config BOOT_X25519_PSA_DEPENDENCIES - bool - select PSA_WANT_ALG_ECDH - select PSA_WANT_ALG_HMAC - select PSA_WANT_ALG_HKDF - select PSA_WANT_ALG_CTR - select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT - select PSA_WANT_KEY_TYPE_DERIVE - select PSA_WANT_KEY_TYPE_AES - select PSA_WANT_ECC_MONTGOMERY_255 - help - Dependencies for x25519 shared-random key encryption and AES - encryption. The PSA_WANT_ALG_CTR and PSA_WANT_KEY_TYPE_AES - enable Counter based block cipher and AES key, and algorithm support, - to use with it; the others are used for shared key decryption - and derivation. - -endif # BOOT_ENCRYPT_IMAGE - -if MBEDTLS_ENABLE_HEAP - -config MBEDTLS_HEAP_SIZE - default 2048 if BOOT_USE_PSA_CRYPTO - help - The PSA internals need to be able to allocate memory for operation - and it uses mbedTLS heap for that. - -endif # MBEDTLS_ENABLE_HEAP - -endif # BOOT_USE_PSA_CRYPTO - menu "MCUBoot settings" config SINGLE_APPLICATION_SLOT @@ -178,7 +124,6 @@ endchoice # BOOT_IMG_HASH_ALG choice BOOT_SIGNATURE_TYPE prompt "Signature type" - default BOOT_SIGNATURE_TYPE_ED25519 if BOARD_NRF54L15PDK_NRF54L15_CPUAPP default BOOT_SIGNATURE_TYPE_RSA config BOOT_SIGNATURE_TYPE_NONE @@ -233,24 +178,13 @@ if BOOT_SIGNATURE_TYPE_ED25519 choice BOOT_ED25519_IMPLEMENTATION prompt "Ecdsa implementation" default BOOT_ED25519_TINYCRYPT - config BOOT_ED25519_TINYCRYPT bool "Use tinycrypt" select BOOT_USE_TINYCRYPT - depends on !NRF_SECURITY - config BOOT_ED25519_MBEDTLS bool "Use mbedTLS" select BOOT_USE_MBEDTLS select MBEDTLS - depends on !NRF_SECURITY - -config BOOT_ED25519_PSA - bool "Use PSA crypto" - select BOOT_USE_PSA_CRYPTO - select BOOT_ED25519_PSA_DEPENDENCIES - select BOOT_X25519_PSA_DEPENDENCIES if BOOT_ENCRYPT_IMAGE - endchoice endif @@ -289,13 +223,9 @@ config MCUBOOT_CLEANUP_ARM_CORE start-up code which can cause a module fault and potentially make the module irrecoverable. -if MBEDTLS - config MBEDTLS_CFG_FILE default "mcuboot-mbedtls-cfg.h" -endif - config BOOT_HW_KEY bool "Use HW key for image verification" default n diff --git a/boot/zephyr/include/mcuboot-mbedtls-cfg.h b/boot/zephyr/include/mcuboot-mbedtls-cfg.h index a46fbb09f..2bab537d7 100644 --- a/boot/zephyr/include/mcuboot-mbedtls-cfg.h +++ b/boot/zephyr/include/mcuboot-mbedtls-cfg.h @@ -23,7 +23,7 @@ #if defined(CONFIG_BOOT_SIGNATURE_TYPE_RSA) || defined(CONFIG_BOOT_ENCRYPT_RSA) #include "config-rsa.h" -#elif defined(CONFIG_BOOT_USE_PSA_CRYPTO) || defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) || \ +#elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) || \ defined(CONFIG_BOOT_ENCRYPT_EC256) || \ (defined(CONFIG_BOOT_ENCRYPT_X25519) && !defined(CONFIG_BOOT_SIGNATURE_TYPE_ED25519)) #include "config-asn1.h" From fa5238475e9addb6edce7aa6c512d33b17308e1f Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 102/238] Revert "[nrf fromlist] boot: Replace boot_encrypt by boot_enc_encrypt and boot_enc_decrypt" This reverts commit b1b4ec39820c1fedd2bb203210425be61071ff83. --- boot/boot_serial/src/boot_serial_encryption.c | 2 +- boot/bootutil/include/bootutil/enc_key.h | 4 +-- boot/bootutil/src/encrypted.c | 31 +++---------------- boot/bootutil/src/image_validate.c | 4 +-- boot/bootutil/src/loader.c | 19 +++++------- 5 files changed, 16 insertions(+), 44 deletions(-) diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index c4bd7d87b..7d3b47c72 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -171,7 +171,7 @@ decrypt_region_inplace(struct boot_loader_state *state, blk_sz = tlv_off - (off + bytes_copied); } } - boot_enc_decrypt(BOOT_CURR_ENC(state), slot, + boot_encrypt(BOOT_CURR_ENC(state), slot, (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index 966f2d6a7..ceb7c21d9 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -59,9 +59,7 @@ int boot_enc_load(struct enc_key_data *enc_state, int slot, const struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs); bool boot_enc_valid(struct enc_key_data *enc_state, int slot); -void boot_enc_encrypt(struct enc_key_data *enc_state, int slot, - uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); -void boot_enc_decrypt(struct enc_key_data *enc_state, int slot, +void boot_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); void boot_enc_zeroize(struct enc_key_data *enc_state); diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index b48f859f6..e8f4a40cd 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -663,13 +663,14 @@ boot_enc_valid(struct enc_key_data *enc_state, int slot) } void -boot_enc_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, +boot_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf) { - struct enc_key_data *enc = &enc_state[slot]; + struct enc_key_data *enc; uint8_t nonce[16]; - /* Nothing to do with size == 0 */ + /* boot_copy_region will call boot_encrypt with sz = 0 when skipping over + the TLVs. */ if (sz == 0) { return; } @@ -681,33 +682,11 @@ boot_enc_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, nonce[14] = (uint8_t)(off >> 8); nonce[15] = (uint8_t)off; + enc = &enc_state[slot]; assert(enc->valid == 1); bootutil_aes_ctr_encrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf); } -void -boot_enc_decrypt(struct enc_key_data *enc_state, int slot, uint32_t off, - uint32_t sz, uint32_t blk_off, uint8_t *buf) -{ - struct enc_key_data *enc = &enc_state[slot]; - uint8_t nonce[16]; - - /* Nothing to do with size == 0 */ - if (sz == 0) { - return; - } - - memset(nonce, 0, 12); - off >>= 4; - nonce[12] = (uint8_t)(off >> 24); - nonce[13] = (uint8_t)(off >> 16); - nonce[14] = (uint8_t)(off >> 8); - nonce[15] = (uint8_t)off; - - assert(enc->valid == 1); - bootutil_aes_ctr_decrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf); -} - /** * Clears encrypted state after use. */ diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index a6155f7b0..4db434d6e 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -162,8 +162,8 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, if (off >= hdr_size && off < tlv_off) { blk_off = (off - hdr_size) & 0xf; - boot_enc_decrypt(enc_state, slot, off - hdr_size, - blk_sz, blk_off, tmp_buf); + boot_encrypt(enc_state, slot, off - hdr_size, + blk_sz, blk_off, tmp_buf); } } #endif diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 9f2843a0d..42a370a79 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1676,15 +1676,9 @@ boot_copy_region(struct boot_loader_state *state, blk_sz = tlv_off - abs_off; } } - if (source_slot == 0) { - boot_enc_encrypt(BOOT_CURR_ENC(state), source_slot, - (abs_off + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, &buf[idx]); - } else { - boot_enc_decrypt(BOOT_CURR_ENC(state), source_slot, - (abs_off + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, &buf[idx]); - } + boot_encrypt(BOOT_CURR_ENC(state), source_slot, + (abs_off + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, &buf[idx]); } } #endif @@ -3190,9 +3184,10 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, * Part of the chunk is encrypted payload */ blk_sz = tlv_off - (bytes_copied); } - boot_enc_decrypt(BOOT_CURR_ENC(state), slot, - (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, cur_dst); + boot_encrypt(BOOT_CURR_ENC(state), slot, + (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, cur_dst); + bytes_copied += chunk_sz; } rc = 0; From ab0e70c27f592409702176e3b4671a98d9d2ab86 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 103/238] Revert "[nrf fromtree] boot: Make boot_enc_valid take slot instead of image index" This reverts commit 3d1c64b983066bd0a3a3319114903a8063ca8374. --- boot/bootutil/include/bootutil/enc_key.h | 3 ++- boot/bootutil/src/encrypted.c | 14 ++++++++++++-- boot/bootutil/src/image_validate.c | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index ceb7c21d9..a86430937 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -58,7 +58,8 @@ int boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, int boot_enc_load(struct enc_key_data *enc_state, int slot, const struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs); -bool boot_enc_valid(struct enc_key_data *enc_state, int slot); +bool boot_enc_valid(struct enc_key_data *enc_state, int image_index, + const struct flash_area *fap); void boot_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); void boot_enc_zeroize(struct enc_key_data *enc_state); diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index e8f4a40cd..313e018ca 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -657,9 +657,19 @@ boot_enc_load(struct enc_key_data *enc_state, int slot, } bool -boot_enc_valid(struct enc_key_data *enc_state, int slot) +boot_enc_valid(struct enc_key_data *enc_state, int image_index, + const struct flash_area *fap) { - return enc_state[slot].valid; + int rc; + + rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fap)); + if (rc < 0) { + /* can't get proper slot number - skip encryption, */ + /* postpone the error for a upper layer */ + return false; + } + + return enc_state[rc].valid; } void diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 4db434d6e..851d667af 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -105,7 +105,7 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, #ifdef MCUBOOT_ENC_IMAGES /* Encrypted images only exist in the secondary slot */ if (MUST_DECRYPT(fap, image_index, hdr) && - !boot_enc_valid(enc_state, 1)) { + !boot_enc_valid(enc_state, image_index, fap)) { return -1; } #endif From 302b002952002be5a64d661b71caa94e77498006 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 104/238] Revert "[nrf fromtree] boot: Simplify copy loop in boot_copy_region" This reverts commit c04fb82970f8fa15e0e6359865214363542e5f18. --- boot/bootutil/src/loader.c | 110 +++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 61 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 42a370a79..102bbe30c 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1571,26 +1571,17 @@ boot_copy_region(struct boot_loader_state *state, int chunk_sz; int rc; #ifdef MCUBOOT_ENC_IMAGES - uint32_t off = off_dst; + uint32_t off; uint32_t tlv_off; size_t blk_off; struct image_header *hdr; uint16_t idx; uint32_t blk_sz; - uint8_t image_index = BOOT_CURR_IMG(state); + uint8_t image_index; bool encrypted_src; bool encrypted_dst; - /* Assuming the secondary slot is source; note that 0 here not only - * means that primary slot is source, but also that there will be - * encryption happening, if it is 1 then there is decryption from - * secondary slot. - */ + /* Assuming the secondary slot is source and needs decryption */ int source_slot = 1; - /* In case of encryption enabled, we may have to do more work than - * just copy bytes */ - bool only_copy = false; -#else - (void)state; #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES struct image_header *hdr; @@ -1598,26 +1589,8 @@ boot_copy_region(struct boot_loader_state *state, TARGET_STATIC uint8_t buf[BUF_SZ] __attribute__((aligned(4))); -#ifdef MCUBOOT_ENC_IMAGES - encrypted_src = (flash_area_get_id(fap_src) != FLASH_AREA_IMAGE_PRIMARY(image_index)); - encrypted_dst = (flash_area_get_id(fap_dst) != FLASH_AREA_IMAGE_PRIMARY(image_index)); - - if (encrypted_src != encrypted_dst) { - if (encrypted_dst) { - /* Need encryption, metadata from the primary slot */ - hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT); - source_slot = 0; - } else { - /* Need decryption, metadata from the secondary slot */ - hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); - source_slot = 1; - } - } else { - /* In case when source and targe is the same area, this means that we - * only have to copy bytes, no encryption or decryption. - */ - only_copy = true; - } +#if !defined(MCUBOOT_ENC_IMAGES) + (void)state; #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES @@ -1644,41 +1617,56 @@ boot_copy_region(struct boot_loader_state *state, } #ifdef MCUBOOT_ENC_IMAGES - /* If only copy, then does not matter if header indicates need for - * encryptio/decryptio, we just copy data. */ - if (!only_copy && IS_ENCRYPTED(hdr)) { - uint32_t abs_off = off + bytes_copied; - if (abs_off < hdr->ih_hdr_size) { - /* do not decrypt header */ - if (abs_off + chunk_sz > hdr->ih_hdr_size) { - /* The lower part of the chunk contains header data */ - blk_off = 0; - blk_sz = chunk_sz - (hdr->ih_hdr_size - abs_off); - idx = hdr->ih_hdr_size - abs_off; - } else { - /* The chunk contains exclusively header data */ - blk_sz = 0; /* nothing to decrypt */ - } + image_index = BOOT_CURR_IMG(state); + encrypted_src = (flash_area_get_id(fap_src) != FLASH_AREA_IMAGE_PRIMARY(image_index)); + encrypted_dst = (flash_area_get_id(fap_dst) != FLASH_AREA_IMAGE_PRIMARY(image_index)); + + if (encrypted_src != encrypted_dst) { + off = off_dst; + + if (encrypted_dst) { + /* Need encryption, metadata from the primary slot */ + hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT); + source_slot = 0; } else { - idx = 0; - blk_sz = chunk_sz; - blk_off = (abs_off - hdr->ih_hdr_size) & 0xf; + /* Need decryption, metadata from the secondary slot */ + hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + source_slot = 1; } - if (blk_sz > 0) - { - tlv_off = BOOT_TLV_OFF(hdr); - if (abs_off + chunk_sz > tlv_off) { - /* do not decrypt TLVs */ - if (abs_off >= tlv_off) { - blk_sz = 0; + if (IS_ENCRYPTED(hdr)) { + uint32_t abs_off = off + bytes_copied; + if (abs_off < hdr->ih_hdr_size) { + /* do not decrypt header */ + if (abs_off + chunk_sz > hdr->ih_hdr_size) { + /* The lower part of the chunk contains header data */ + blk_off = 0; + blk_sz = chunk_sz - (hdr->ih_hdr_size - abs_off); + idx = hdr->ih_hdr_size - abs_off; } else { - blk_sz = tlv_off - abs_off; + /* The chunk contains exclusively header data */ + blk_sz = 0; /* nothing to decrypt */ + } + } else { + idx = 0; + blk_sz = chunk_sz; + blk_off = (abs_off - hdr->ih_hdr_size) & 0xf; + } + + if (blk_sz > 0) { + tlv_off = BOOT_TLV_OFF(hdr); + if (abs_off + chunk_sz > tlv_off) { + /* do not decrypt TLVs */ + if (abs_off >= tlv_off) { + blk_sz = 0; + } else { + blk_sz = tlv_off - abs_off; + } } + boot_encrypt(BOOT_CURR_ENC(state), source_slot, + (abs_off + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, &buf[idx]); } - boot_encrypt(BOOT_CURR_ENC(state), source_slot, - (abs_off + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, &buf[idx]); } } #endif From 7e2f568929414c1894b96688ff994394bbc6b6d9 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 105/238] Revert "[nrf fromtree] boot: Remove image_index from boot_encrypt" This reverts commit 8b0d958ee05c6f05bdf26c50ee2754c092618824. --- boot/boot_serial/src/boot_serial_encryption.c | 8 ++++---- boot/bootutil/include/bootutil/enc_key.h | 5 +++-- boot/bootutil/src/encrypted.c | 14 +++++++++++--- boot/bootutil/src/image_validate.c | 7 ++----- boot/bootutil/src/loader.c | 13 +++++++------ 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index 7d3b47c72..cf9040b30 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -125,11 +125,10 @@ decrypt_region_inplace(struct boot_loader_state *state, size_t blk_off; uint16_t idx; uint32_t blk_sz; - int slot = flash_area_id_to_multi_image_slot(BOOT_CURR_IMG(state), - flash_area_get_id(fap)); + uint8_t image_index; + uint8_t buf[sz] __attribute__((aligned)); assert(sz <= sizeof buf); - assert(slot >= 0); bytes_copied = 0; while (bytes_copied < sz) { @@ -144,6 +143,7 @@ decrypt_region_inplace(struct boot_loader_state *state, return BOOT_EFLASH; } + image_index = BOOT_CURR_IMG(state); if (IS_ENCRYPTED(hdr)) { blk_sz = chunk_sz; idx = 0; @@ -171,7 +171,7 @@ decrypt_region_inplace(struct boot_loader_state *state, blk_sz = tlv_off - (off + bytes_copied); } } - boot_encrypt(BOOT_CURR_ENC(state), slot, + boot_encrypt(BOOT_CURR_ENC(state), image_index, flash_area_get_id(fap), (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index a86430937..8db6e72c8 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -60,8 +60,9 @@ int boot_enc_load(struct enc_key_data *enc_state, int slot, struct boot_status *bs); bool boot_enc_valid(struct enc_key_data *enc_state, int image_index, const struct flash_area *fap); -void boot_encrypt(struct enc_key_data *enc_state, int slot, - uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); +void boot_encrypt(struct enc_key_data *enc_state, int image_index, + int fa_id, uint32_t off, uint32_t sz, + uint32_t blk_off, uint8_t *buf); void boot_enc_zeroize(struct enc_key_data *enc_state); #ifdef __cplusplus diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index 313e018ca..f3516ac74 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -673,11 +673,13 @@ boot_enc_valid(struct enc_key_data *enc_state, int image_index, } void -boot_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, - uint32_t sz, uint32_t blk_off, uint8_t *buf) +boot_encrypt(struct enc_key_data *enc_state, int image_index, + int fa_id, uint32_t off, uint32_t sz, + uint32_t blk_off, uint8_t *buf) { struct enc_key_data *enc; uint8_t nonce[16]; + int rc; /* boot_copy_region will call boot_encrypt with sz = 0 when skipping over the TLVs. */ @@ -692,7 +694,13 @@ boot_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, nonce[14] = (uint8_t)(off >> 8); nonce[15] = (uint8_t)off; - enc = &enc_state[slot]; + rc = flash_area_id_to_multi_image_slot(image_index, fa_id); + if (rc < 0) { + assert(0); + return; + } + + enc = &enc_state[rc]; assert(enc->valid == 1); bootutil_aes_ctr_encrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf); } diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 851d667af..09b8082ec 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -157,13 +157,10 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, #ifdef MCUBOOT_ENC_IMAGES if (MUST_DECRYPT(fap, image_index, hdr)) { /* Only payload is encrypted (area between header and TLVs) */ - int slot = flash_area_id_to_multi_image_slot(image_index, - flash_area_get_id(fap)); - if (off >= hdr_size && off < tlv_off) { blk_off = (off - hdr_size) & 0xf; - boot_encrypt(enc_state, slot, off - hdr_size, - blk_sz, blk_off, tmp_buf); + boot_encrypt(enc_state, image_index, flash_area_get_id(fap), off - hdr_size, + blk_sz, blk_off, tmp_buf); } } #endif diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 102bbe30c..e2dd0f08e 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1574,14 +1574,13 @@ boot_copy_region(struct boot_loader_state *state, uint32_t off; uint32_t tlv_off; size_t blk_off; + int enc_area_id; struct image_header *hdr; uint16_t idx; uint32_t blk_sz; uint8_t image_index; bool encrypted_src; bool encrypted_dst; - /* Assuming the secondary slot is source and needs decryption */ - int source_slot = 1; #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES struct image_header *hdr; @@ -1627,11 +1626,11 @@ boot_copy_region(struct boot_loader_state *state, if (encrypted_dst) { /* Need encryption, metadata from the primary slot */ hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT); - source_slot = 0; + enc_area_id = FLASH_AREA_IMAGE_PRIMARY(image_index); } else { /* Need decryption, metadata from the secondary slot */ hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); - source_slot = 1; + enc_area_id = FLASH_AREA_IMAGE_SECONDARY(image_index); } if (IS_ENCRYPTED(hdr)) { @@ -1663,7 +1662,7 @@ boot_copy_region(struct boot_loader_state *state, blk_sz = tlv_off - abs_off; } } - boot_encrypt(BOOT_CURR_ENC(state), source_slot, + boot_encrypt(BOOT_CURR_ENC(state), image_index, enc_area_id, (abs_off + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } @@ -3126,11 +3125,13 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, uint32_t chunk_sz; uint32_t max_sz = 1024; uint16_t idx; + uint8_t image_index; uint8_t * cur_dst; int area_id; int rc; uint8_t * ram_dst = (void *)(IMAGE_RAM_BASE + img_dst); + image_index = BOOT_CURR_IMG(state); area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot); rc = flash_area_open(area_id, &fap_src); if (rc != 0){ @@ -3172,7 +3173,7 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, * Part of the chunk is encrypted payload */ blk_sz = tlv_off - (bytes_copied); } - boot_encrypt(BOOT_CURR_ENC(state), slot, + boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, cur_dst); From 8d87b786de8ac0196c5d6b6e35c1676149403bbf Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 106/238] Revert "[nrf fromtree] Fix style issues" This reverts commit a92356827eb2e3b28da47d8007e253896c441c30. --- boot/bootutil/src/loader.c | 3 ++- boot/bootutil/src/swap_move.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index e2dd0f08e..591518a77 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1652,7 +1652,8 @@ boot_copy_region(struct boot_loader_state *state, blk_off = (abs_off - hdr->ih_hdr_size) & 0xf; } - if (blk_sz > 0) { + if (blk_sz > 0) + { tlv_off = BOOT_TLV_OFF(hdr); if (abs_off + chunk_sz > tlv_off) { /* do not decrypt TLVs */ diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 4dce64425..5e6723bb6 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -86,7 +86,7 @@ boot_read_image_header(struct boot_loader_state *state, int slot, off = 0; if (bs && !boot_status_is_reset(bs)) { - boot_find_status(BOOT_CURR_IMG(state), &fap); + boot_find_status(BOOT_CURR_IMG(state), &fap); if (fap == NULL || boot_read_swap_size(fap, &swap_size)) { rc = BOOT_EFLASH; goto done; From 98f83a1b72a661ecd9554104849cf48d2e6c651b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 107/238] Revert "[nrf fromtree] boot: Reduce repeating code in boot_decrypt_and_copy_image_to_sram" This reverts commit c77f4110ceb8fecec61d117027e2fdc763f4ebf4. --- boot/bootutil/src/loader.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 591518a77..c976aa087 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -3168,15 +3168,21 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, cur_dst = ram_dst + bytes_copied; blk_sz = chunk_sz; idx = 0; - blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf; if (bytes_copied + chunk_sz > tlv_off) { /* Going over TLV section * Part of the chunk is encrypted payload */ + blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf; blk_sz = tlv_off - (bytes_copied); + boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, + (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, cur_dst); + } else { + /* Image encrypted payload section */ + blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf; + boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, + (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, cur_dst); } - boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, - (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, cur_dst); bytes_copied += chunk_sz; } From 499864b561a61c7654f2b8833eac1f06ed81f6b0 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 108/238] Revert "[nrf fromtree] boot: Change boot_enc_load to take slot number instead of image" This reverts commit 852f9af2a37a16b62b95ccc8257e9069e71f2361. --- boot/boot_serial/src/boot_serial_encryption.c | 7 +++++-- boot/bootutil/include/bootutil/enc_key.h | 2 +- boot/bootutil/src/encrypted.c | 9 ++++++++- boot/bootutil/src/loader.c | 20 ++++++++++--------- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index cf9040b30..6717826f1 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -36,7 +36,7 @@ boot_image_validate_encrypted(const struct flash_area *fa_p, memset(&boot_data, 0, sizeof(struct boot_loader_state)); image_index = BOOT_CURR_IMG(state); if(IS_ENCRYPTED(hdr)) { - rc = boot_enc_load(BOOT_CURR_ENC(state), 1, hdr, fa_p, bs); + rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs); if (rc < 0) { FIH_RET(fih_rc); } @@ -218,6 +218,7 @@ decrypt_image_inplace(const struct flash_area *fa_p, size_t sect_size; size_t sect_count; size_t sect; + uint8_t image_index; struct flash_sector sector; memset(&boot_data, 0, sizeof(struct boot_loader_state)); @@ -227,6 +228,8 @@ decrypt_image_inplace(const struct flash_area *fa_p, rc = flash_area_get_sector(fa_p, boot_status_off(fa_p), §or); + image_index = BOOT_CURR_IMG(state); + if(IS_ENCRYPTED(hdr)) { #if 0 //Skip this step?, the image will just not boot if it's not decrypted properly static uint8_t tmpbuf[BOOT_TMPBUF_SZ]; @@ -238,7 +241,7 @@ decrypt_image_inplace(const struct flash_area *fa_p, #endif memset(&boot_data, 0, sizeof(struct boot_loader_state)); /* Load the encryption keys into cache */ - rc = boot_enc_load(BOOT_CURR_ENC(state), 0, hdr, fa_p, bs); + rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs); if (rc < 0) { FIH_RET(fih_rc); } diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index 8db6e72c8..8dd7ca8b7 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -55,7 +55,7 @@ int boot_enc_init(struct enc_key_data *enc_state, uint8_t slot); int boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot); int boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, const struct boot_status *bs); -int boot_enc_load(struct enc_key_data *enc_state, int slot, +int boot_enc_load(struct enc_key_data *enc_state, int image_index, const struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs); bool boot_enc_valid(struct enc_key_data *enc_state, int image_index, diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index f3516ac74..09b9a78df 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -607,7 +607,7 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey) * Load encryption key. */ int -boot_enc_load(struct enc_key_data *enc_state, int slot, +boot_enc_load(struct enc_key_data *enc_state, int image_index, const struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs) { @@ -619,8 +619,15 @@ boot_enc_load(struct enc_key_data *enc_state, int slot, #else uint8_t buf[EXPECTED_ENC_LEN]; #endif + uint8_t slot; int rc; + rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fap)); + if (rc < 0) { + return rc; + } + slot = rc; + /* Already loaded... */ if (enc_state[slot].valid) { return 1; diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index c976aa087..4a93b8dbd 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -854,6 +854,7 @@ boot_image_check(struct boot_loader_state *state, struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs) { TARGET_STATIC uint8_t tmpbuf[BOOT_TMPBUF_SZ]; + uint8_t image_index; int rc; FIH_DECLARE(fih_rc, FIH_FAILURE); @@ -864,11 +865,13 @@ boot_image_check(struct boot_loader_state *state, struct image_header *hdr, (void)bs; (void)rc; + image_index = BOOT_CURR_IMG(state); + /* In the case of ram loading the image has already been decrypted as it is * decrypted when copied in ram */ #if defined(MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_RAM_LOAD) - if (MUST_DECRYPT(fap, BOOT_CURR_IMG(state), hdr)) { - rc = boot_enc_load(BOOT_CURR_ENC(state), 1, hdr, fap, bs); + if (MUST_DECRYPT(fap, image_index, hdr)) { + rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap, bs); if (rc < 0) { FIH_RET(fih_rc); } @@ -878,9 +881,8 @@ boot_image_check(struct boot_loader_state *state, struct image_header *hdr, } #endif - FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), - BOOT_CURR_IMG(state), hdr, fap, tmpbuf, BOOT_TMPBUF_SZ, - NULL, 0, NULL); + FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), image_index, + hdr, fap, tmpbuf, BOOT_TMPBUF_SZ, NULL, 0, NULL); FIH_RET(fih_rc); } @@ -1772,7 +1774,7 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) #ifdef MCUBOOT_ENC_IMAGES if (IS_ENCRYPTED(boot_img_hdr(state, BOOT_SECONDARY_SLOT))) { - rc = boot_enc_load(BOOT_CURR_ENC(state), BOOT_SECONDARY_SLOT, + rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, boot_img_hdr(state, BOOT_SECONDARY_SLOT), fap_secondary_slot, bs); @@ -1896,7 +1898,7 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) #ifdef MCUBOOT_ENC_IMAGES if (IS_ENCRYPTED(hdr)) { fap = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); - rc = boot_enc_load(BOOT_CURR_ENC(state), 0, hdr, fap, bs); + rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap, bs); assert(rc >= 0); if (rc == 0) { @@ -1920,7 +1922,7 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); if (IS_ENCRYPTED(hdr)) { fap = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - rc = boot_enc_load(BOOT_CURR_ENC(state), 1, hdr, fap, bs); + rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap, bs); assert(rc >= 0); if (rc == 0) { @@ -3147,7 +3149,7 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, goto done; } - rc = boot_enc_load(BOOT_CURR_ENC(state), slot, hdr, fap_src, &bs); + rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap_src, &bs); if (rc < 0) { goto done; } From d2e060b86c16d677a9c4bb56f56d23dfca603f96 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 109/238] Revert "[nrf fromtree] boot: Move encryption context invalidation to boot_enc_drop." This reverts commit 8d04aa0c63567d9c7bf6fa2c7205e108b0e8dbde. --- boot/bootutil/src/encrypted.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index 09b9a78df..d8e3292ec 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -347,7 +347,6 @@ int boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot) { bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr); - enc_state[slot].valid = 0; return 0; } @@ -360,6 +359,7 @@ boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]); if (rc != 0) { boot_enc_drop(enc_state, slot); + enc_state[slot].valid = 0; return -1; } From 9553f404e8b6c776899ddfde742d061e28c95b6f Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 110/238] Revert "[nrf fromtree] boot: Rename boot_enc_decrypt to boot_decrypt_key" This reverts commit dd38c001851caa797c01d95193a11ebbc3cb8a2f. --- boot/bootutil/include/bootutil/enc_key.h | 4 +--- boot/bootutil/src/bootutil_misc.c | 2 +- boot/bootutil/src/encrypted.c | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index 8dd7ca8b7..d8dab9013 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -48,9 +48,6 @@ struct enc_key_data { extern const struct bootutil_key bootutil_enc_key; struct boot_status; -/* Decrypt random, symmetric encryption key */ -int boot_decrypt_key(const uint8_t *buf, uint8_t *enckey); - int boot_enc_init(struct enc_key_data *enc_state, uint8_t slot); int boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot); int boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, @@ -58,6 +55,7 @@ int boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, int boot_enc_load(struct enc_key_data *enc_state, int image_index, const struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs); +int boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey); bool boot_enc_valid(struct enc_key_data *enc_state, int image_index, const struct flash_area *fap); void boot_encrypt(struct enc_key_data *enc_state, int image_index, diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index e06ec83d6..87b863507 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -283,7 +283,7 @@ boot_read_enc_key(const struct flash_area *fap, uint8_t slot, struct boot_status } /* Only try to decrypt non-erased TLV metadata */ if (i != BOOT_ENC_TLV_ALIGN_SIZE) { - rc = boot_decrypt_key(bs->enctlv[slot], bs->enckey[slot]); + rc = boot_enc_decrypt(bs->enctlv[slot], bs->enckey[slot]); } } #else diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index d8e3292ec..44975cc49 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -415,7 +415,7 @@ static int fake_rng(void *p_rng, unsigned char *output, size_t len) * @param enckey An AES-128 or AES-256 key sized buffer to store to plain key. */ int -boot_decrypt_key(const uint8_t *buf, uint8_t *enckey) +boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey) { #if defined(MCUBOOT_ENCRYPT_RSA) bootutil_rsa_context rsa; @@ -660,7 +660,7 @@ boot_enc_load(struct enc_key_data *enc_state, int image_index, return -1; } - return boot_decrypt_key(buf, bs->enckey[slot]); + return boot_enc_decrypt(buf, bs->enckey[slot]); } bool From 30e5e62a1a4940ab85795fcc2c6fb50128691011 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 111/238] Revert "[nrf fromtree] boot: Remove pointless slot identification" This reverts commit eb5042bf352bf288ed197ef8fcca504eaef4cf31. --- boot/boot_serial/src/boot_serial_encryption.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index 6717826f1..51d25024e 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -40,6 +40,10 @@ boot_image_validate_encrypted(const struct flash_area *fa_p, if (rc < 0) { FIH_RET(fih_rc); } + rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fa_p)); + if (rc < 0) { + FIH_RET(fih_rc); + } rc = boot_enc_set_key(BOOT_CURR_ENC(state), 1, bs); if (rc < 0) { FIH_RET(fih_rc); From 69a1d527d52be9360c3a3869617341988743ca8f Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 112/238] Revert "[nrf fromtree] bootutil: Keep image encrypted in scratch area" This reverts commit 3a8716bbe8783227e7cc5f05f901c8cffd735fca. --- boot/boot_serial/src/boot_serial_encryption.c | 2 +- boot/bootutil/include/bootutil/enc_key.h | 2 +- boot/bootutil/src/encrypted.c | 4 +- boot/bootutil/src/image_validate.c | 2 +- boot/bootutil/src/loader.c | 38 +++++++++---------- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index 51d25024e..6201e6b69 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -175,7 +175,7 @@ decrypt_region_inplace(struct boot_loader_state *state, blk_sz = tlv_off - (off + bytes_copied); } } - boot_encrypt(BOOT_CURR_ENC(state), image_index, flash_area_get_id(fap), + boot_encrypt(BOOT_CURR_ENC(state), image_index, fap, (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index d8dab9013..768dd8e7e 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -59,7 +59,7 @@ int boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey); bool boot_enc_valid(struct enc_key_data *enc_state, int image_index, const struct flash_area *fap); void boot_encrypt(struct enc_key_data *enc_state, int image_index, - int fa_id, uint32_t off, uint32_t sz, + const struct flash_area *fap, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); void boot_enc_zeroize(struct enc_key_data *enc_state); diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index 44975cc49..212774e3a 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -681,7 +681,7 @@ boot_enc_valid(struct enc_key_data *enc_state, int image_index, void boot_encrypt(struct enc_key_data *enc_state, int image_index, - int fa_id, uint32_t off, uint32_t sz, + const struct flash_area *fap, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf) { struct enc_key_data *enc; @@ -701,7 +701,7 @@ boot_encrypt(struct enc_key_data *enc_state, int image_index, nonce[14] = (uint8_t)(off >> 8); nonce[15] = (uint8_t)off; - rc = flash_area_id_to_multi_image_slot(image_index, fa_id); + rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fap)); if (rc < 0) { assert(0); return; diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 09b8082ec..5043d385a 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -159,7 +159,7 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, /* Only payload is encrypted (area between header and TLVs) */ if (off >= hdr_size && off < tlv_off) { blk_off = (off - hdr_size) & 0xf; - boot_encrypt(enc_state, image_index, flash_area_get_id(fap), off - hdr_size, + boot_encrypt(enc_state, image_index, fap, off - hdr_size, blk_sz, blk_off, tmp_buf); } } diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 4a93b8dbd..d35b6910c 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1576,13 +1576,10 @@ boot_copy_region(struct boot_loader_state *state, uint32_t off; uint32_t tlv_off; size_t blk_off; - int enc_area_id; struct image_header *hdr; uint16_t idx; uint32_t blk_sz; uint8_t image_index; - bool encrypted_src; - bool encrypted_dst; #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES struct image_header *hdr; @@ -1619,22 +1616,25 @@ boot_copy_region(struct boot_loader_state *state, #ifdef MCUBOOT_ENC_IMAGES image_index = BOOT_CURR_IMG(state); - encrypted_src = (flash_area_get_id(fap_src) != FLASH_AREA_IMAGE_PRIMARY(image_index)); - encrypted_dst = (flash_area_get_id(fap_dst) != FLASH_AREA_IMAGE_PRIMARY(image_index)); - - if (encrypted_src != encrypted_dst) { + if ((flash_area_get_id(fap_src) == FLASH_AREA_IMAGE_SECONDARY(image_index) || + flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index)) && + !(flash_area_get_id(fap_src) == FLASH_AREA_IMAGE_SECONDARY(image_index) && + flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index))) { + /* assume the secondary slot as src, needs decryption */ + hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); +#if !defined(MCUBOOT_SWAP_USING_MOVE) + off = off_src; + if (flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index)) { + /* might need encryption (metadata from the primary slot) */ + hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT); + off = off_dst; + } +#else off = off_dst; - - if (encrypted_dst) { - /* Need encryption, metadata from the primary slot */ + if (flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index)) { hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT); - enc_area_id = FLASH_AREA_IMAGE_PRIMARY(image_index); - } else { - /* Need decryption, metadata from the secondary slot */ - hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); - enc_area_id = FLASH_AREA_IMAGE_SECONDARY(image_index); } - +#endif if (IS_ENCRYPTED(hdr)) { uint32_t abs_off = off + bytes_copied; if (abs_off < hdr->ih_hdr_size) { @@ -1665,7 +1665,7 @@ boot_copy_region(struct boot_loader_state *state, blk_sz = tlv_off - abs_off; } } - boot_encrypt(BOOT_CURR_ENC(state), image_index, enc_area_id, + boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src, (abs_off + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } @@ -3175,13 +3175,13 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, * Part of the chunk is encrypted payload */ blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf; blk_sz = tlv_off - (bytes_copied); - boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, + boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src, (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, cur_dst); } else { /* Image encrypted payload section */ blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf; - boot_encrypt(BOOT_CURR_ENC(state), image_index, area_id, + boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src, (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, cur_dst); } From 174d00bf24f62e78149dc28b65318021646332e3 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 113/238] Revert "[nrf fromtree] boot: Fix ASN.1 for mbedtls >= 3.1" This reverts commit 647a928315b7e004e663d60b92c198e668b90b41. --- boot/bootutil/include/bootutil/crypto/common.h | 9 --------- boot/bootutil/include/bootutil/crypto/ecdsa.h | 16 ++++++++-------- boot/bootutil/src/encrypted.c | 12 ++++++------ boot/bootutil/src/image_ed25519.c | 4 ++-- 4 files changed, 16 insertions(+), 25 deletions(-) diff --git a/boot/bootutil/include/bootutil/crypto/common.h b/boot/bootutil/include/bootutil/crypto/common.h index 1fb5c5835..c765fe1f3 100644 --- a/boot/bootutil/include/bootutil/crypto/common.h +++ b/boot/bootutil/include/bootutil/crypto/common.h @@ -17,13 +17,4 @@ #define MBEDTLS_CONTEXT_MEMBER(X) X #endif -/* Newer versions of Mbed TLS have removed the private accessor requirement for - * the ASN1 fields. - */ -#if (MBEDTLS_VERSION_NUMBER >= 0x03000000) && (MBEDTLS_VERSION_NUMBER < 0x03010000) -#define ASN1_CONTEXT_MEMBER(X) MBEDTLS_PRIVATE(X) -#else -#define ASN1_CONTEXT_MEMBER(X) X -#endif - #endif /* __BOOTUTIL_CRYPTO_COMMON_H__ */ diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index 85355f20c..450450dc3 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -109,13 +109,13 @@ static int bootutil_import_key(uint8_t **cp, uint8_t *end) return -2; } /* id-ecPublicKey (RFC5480) */ - if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || - memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { + if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || + memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { return -3; } /* namedCurve (RFC5480) */ - if (param.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 || - memcmp(param.ASN1_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { + if (param.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 || + memcmp(param.MBEDTLS_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { return -4; } /* ECPoint (RFC5480) */ @@ -521,12 +521,12 @@ static int bootutil_parse_eckey(bootutil_ecdsa_context *ctx, uint8_t **p, uint8_ if (mbedtls_asn1_get_alg(p, end, &alg, ¶m)) { return -2; } - if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || - memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { + if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || + memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { return -3; } - if (param.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1|| - memcmp(param.ASN1_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { + if (param.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1|| + memcmp(param.MBEDTLS_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { return -4; } diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index 212774e3a..39e34dbd3 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -126,12 +126,12 @@ parse_ec256_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key) return -5; } - if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || - memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { + if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || + memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { return -6; } - if (param.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 || - memcmp(param.ASN1_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { + if (param.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 || + memcmp(param.MBEDTLS_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) { return -7; } @@ -203,8 +203,8 @@ parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key) return -4; } - if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || - memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { + if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || + memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { return -5; } diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 7a597d4c0..c51fea494 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -45,8 +45,8 @@ bootutil_import_key(uint8_t **cp, uint8_t *end) return -2; } - if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ed25519_pubkey_oid) - 1 || - memcmp(alg.ASN1_CONTEXT_MEMBER(p), ed25519_pubkey_oid, sizeof(ed25519_pubkey_oid) - 1)) { + if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ed25519_pubkey_oid) - 1 || + memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ed25519_pubkey_oid, sizeof(ed25519_pubkey_oid) - 1)) { return -3; } From 520a6c6b78aea3af8978152bc7b7215c42032aaa Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 114/238] Revert "[nrf fromlist] imgtool: Add support for calculating SHA512" This reverts commit 7aaeb636812f7e5b0b901a1894916dbfd5334f3a. --- scripts/imgtool/image.py | 111 +++++++-------------------------------- scripts/imgtool/main.py | 8 +-- 2 files changed, 22 insertions(+), 97 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index 53b19ef1d..5c4732b53 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -40,8 +40,6 @@ from .boot_record import create_sw_component_data from .keys import rsa, ecdsa, x25519 -from collections import namedtuple - IMAGE_MAGIC = 0x96f3b83d IMAGE_HEADER_SIZE = 32 BIN_EXT = "bin" @@ -67,7 +65,6 @@ 'PUBKEY': 0x02, 'SHA256': 0x10, 'SHA384': 0x11, - 'SHA512': 0x12, 'RSA2048': 0x20, 'ECDSASIG': 0x22, 'RSA3072': 0x23, @@ -138,73 +135,11 @@ def get(self): return header + bytes(self.buf) -SHAAndAlgT = namedtuple('SHAAndAlgT', ['sha', 'alg']) - -TLV_SHA_TO_SHA_AND_ALG = { - TLV_VALUES['SHA256'] : SHAAndAlgT('256', hashlib.sha256), - TLV_VALUES['SHA384'] : SHAAndAlgT('384', hashlib.sha384), - TLV_VALUES['SHA512'] : SHAAndAlgT('512', hashlib.sha512), -} - - -USER_SHA_TO_ALG_AND_TLV = { - 'auto' : (hashlib.sha256, 'SHA256'), - '256' : (hashlib.sha256, 'SHA256'), - '384' : (hashlib.sha384, 'SHA384'), - '512' : (hashlib.sha512, 'SHA512') -} - - -def is_sha_tlv(tlv): - return tlv in TLV_SHA_TO_SHA_AND_ALG.keys() - - -def tlv_sha_to_sha(tlv): - return TLV_SHA_TO_SHA_AND_ALG[tlv].sha - - -# Auto selecting hash algorithm for type(key) -ALLOWED_KEY_SHA = { - keys.ECDSA384P1 : ['384'], - keys.ECDSA384P1Public : ['384'], - keys.ECDSA256P1 : ['256'], - keys.RSA : ['256'], - # This two are set to 256 for compatibility, the right would be 512 - keys.Ed25519 : ['256', '512'], - keys.X25519 : ['256', '512'] -} - -def key_and_user_sha_to_alg_and_tlv(key, user_sha): - """Matches key and user requested sha to sha alogrithm and TLV name. - - The returned tuple will contain hash functions and TVL name. - The function is designed to succeed or completely fail execution, - as providing incorrect pair here basically prevents doing - any more work. - """ - if key is None: - # If key is none, we allow whatever user has selected for sha - return USER_SHA_TO_ALG_AND_TLV[user_sha] - - # If key is not None, then we have to filter hash to only allowed - allowed = None - try: - allowed = ALLOWED_KEY_SHA[type(key)] - except KeyError: - raise click.UsageError("Colud not find allowed hash algorithms for {}" - .format(type(key))) - if user_sha == 'auto': - return USER_SHA_TO_ALG_AND_TLV[allowed[0]] - - if user_sha in allowed: - return USER_SHA_TO_ALG_AND_TLV[user_sha] - - raise click.UsageError("Key {} can not be used with --sha {}; allowed sha are one of {}" - .format(key.sig_type(), user_sha, allowed)) - - def get_digest(tlv_type, hash_region): - sha = TLV_SHA_TO_SHA_AND_ALG[tlv_type].alg() + if tlv_type == TLV_VALUES["SHA384"]: + sha = hashlib.sha384() + elif tlv_type == TLV_VALUES["SHA256"]: + sha = hashlib.sha256() sha.update(hash_region) return sha.digest() @@ -212,16 +147,9 @@ def get_digest(tlv_type, hash_region): def tlv_matches_key_type(tlv_type, key): """Check if provided key matches to TLV record in the image""" - try: - # We do not need the result here, and the key_and_user_sha_to_alg_and_tlv - # will either succeed finding match or rise exception, so on success we - # return True, on exception we return False. - _, _ = key_and_user_sha_to_alg_and_tlv(key, tlv_sha_to_sha(tlv_type)) - return True - except: - pass - - return False + return (key is None or + type(key) == keys.ECDSA384P1 and tlv_type == TLV_VALUES["SHA384"] or + type(key) != keys.ECDSA384P1 and tlv_type == TLV_VALUES["SHA256"]) class Image: @@ -408,13 +336,17 @@ def ecies_hkdf(self, enckey, plainkey): def create(self, key, public_key_format, enckey, dependencies=None, sw_type=None, custom_tlvs=None, encrypt_keylen=128, clear=False, - fixed_sig=None, pub_key=None, vector_to_sign=None, user_sha='auto'): + fixed_sig=None, pub_key=None, vector_to_sign=None): self.enckey = enckey - # key decides on sha, then pub_key; of both are none default is used - check_key = key if key is not None else pub_key - hash_algorithm, hash_tlv = key_and_user_sha_to_alg_and_tlv(check_key, user_sha) - + # Check what hashing algorithm should be used + if (key and isinstance(key, ecdsa.ECDSA384P1) + or pub_key and isinstance(pub_key, ecdsa.ECDSA384P1Public)): + hash_algorithm = hashlib.sha384 + hash_tlv = "SHA384" + else: + hash_algorithm = hashlib.sha256 + hash_tlv = "SHA256" # Calculate the hash of the public key if key is not None: pub = key.get_public_bytes() @@ -534,14 +466,11 @@ def create(self, key, public_key_format, enckey, dependencies=None, tlv = TLV(self.endian) - # These signature is done over sha of image. In case of - # EC signatures so called Pure algorithm, designated to be run - # over entire message is used with sha of image as message, - # so, for example, in case of ED25519 we have here SHAxxx-ED25519-SHA512. + # Note that ecdsa wants to do the hashing itself, which means + # we get to hash it twice. sha = hash_algorithm() sha.update(self.payload) digest = sha.digest() - message = digest; tlv.add(hash_tlv, digest) if vector_to_sign == 'payload': @@ -570,7 +499,7 @@ def create(self, key, public_key_format, enckey, dependencies=None, sig = key.sign(bytes(self.payload)) else: print(os.path.basename(__file__) + ": sign the digest") - sig = key.sign_digest(message) + sig = key.sign_digest(digest) tlv.add(key.sig_tlv(), sig) self.signature = sig elif fixed_sig is not None and key is None: @@ -749,7 +678,7 @@ def verify(imgfile, key): while tlv_off < tlv_end: tlv = b[tlv_off:tlv_off + TLV_SIZE] tlv_type, _, tlv_len = struct.unpack('BBH', tlv) - if is_sha_tlv(tlv_type): + if tlv_type == TLV_VALUES["SHA256"] or tlv_type == TLV_VALUES["SHA384"]: if not tlv_matches_key_type(tlv_type, key): return VerifyResult.KEY_MISMATCH, None, None off = tlv_off + TLV_SIZE diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index 848fd3110..cc2cf9c58 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -72,7 +72,6 @@ def gen_x25519(keyfile, passwd): 'x25519': gen_x25519, } valid_formats = ['openssl', 'pkcs8'] -valid_sha = [ 'auto', '256', '384', '512' ] def load_signature(sigfile): @@ -402,9 +401,6 @@ def convert(self, value, param, ctx): @click.option('--sig-out', metavar='filename', help='Path to the file to which signature will be written. ' 'The image signature will be encoded as base64 formatted string') -@click.option('--sha', 'user_sha', type=click.Choice(valid_sha), default='auto', - help='selected sha algorithm to use; defaults to "auto" which is 256 if ' - 'no cryptographic signature is used, or default for signature type') @click.option('--vector-to-sign', type=click.Choice(['payload', 'digest']), help='send to OUTFILE the payload or payload''s digest instead ' 'of complied image. These data can be used for external image ' @@ -417,7 +413,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, endian, encrypt_keylen, encrypt, infile, outfile, dependencies, load_addr, hex_addr, erased_val, save_enctlv, security_counter, boot_record, custom_tlv, rom_fixed, max_align, clear, fix_sig, - fix_sig_pubkey, sig_out, user_sha, vector_to_sign, non_bootable): + fix_sig_pubkey, sig_out, vector_to_sign, non_bootable): if confirm: # Confirmed but non-padded images don't make much sense, because @@ -485,7 +481,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, img.create(key, public_key_format, enckey, dependencies, boot_record, custom_tlvs, int(encrypt_keylen), clear, baked_signature, - pub_key, vector_to_sign, user_sha) + pub_key, vector_to_sign) img.save(outfile, hex_addr) if sig_out is not None: From ae6870faae03dc223760c60e6542e2cf30112468 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 115/238] Revert "[nrf fromtree] imgtool: Add --non-bootable flag" This reverts commit 300c41cd4258478036adf77c42662b9d51170330. --- scripts/imgtool/image.py | 6 +----- scripts/imgtool/main.py | 7 ++----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index 5c4732b53..a30d53bf2 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -159,8 +159,7 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, slot_size=0, max_sectors=DEFAULT_MAX_SECTORS, overwrite_only=False, endian="little", load_addr=0, rom_fixed=None, erased_val=None, save_enctlv=False, - security_counter=None, max_align=None, - non_bootable=False): + security_counter=None, max_align=None): if load_addr and rom_fixed: raise click.UsageError("Can not set rom_fixed and load_addr at the same time") @@ -184,7 +183,6 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, self.save_enctlv = save_enctlv self.enctlv_len = 0 self.max_align = max(DEFAULT_MAX_ALIGN, align) if max_align is None else int(max_align) - self.non_bootable = non_bootable if self.max_align == DEFAULT_MAX_ALIGN: self.boot_magic = bytes([ @@ -569,8 +567,6 @@ def add_header(self, enckey, protected_tlv_size, aes_length=128): flags |= IMAGE_F['RAM_LOAD'] if self.rom_fixed: flags |= IMAGE_F['ROM_FIXED'] - if self.non_bootable: - flags |= IMAGE_F['NON_BOOTABLE'] e = STRUCT_ENDIAN_DICT[self.endian] fmt = (e + diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index cc2cf9c58..f70a8bf51 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -314,8 +314,6 @@ def convert(self, value, param, ctx): @click.argument('outfile') @click.argument('infile') -@click.option('--non-bootable', default=False, is_flag=True, - help='Mark the image as non-bootable.') @click.option('--custom-tlv', required=False, nargs=2, default=[], multiple=True, metavar='[tag] [value]', help='Custom TLV that will be placed into protected area. ' @@ -413,7 +411,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, endian, encrypt_keylen, encrypt, infile, outfile, dependencies, load_addr, hex_addr, erased_val, save_enctlv, security_counter, boot_record, custom_tlv, rom_fixed, max_align, clear, fix_sig, - fix_sig_pubkey, sig_out, vector_to_sign, non_bootable): + fix_sig_pubkey, sig_out, vector_to_sign): if confirm: # Confirmed but non-padded images don't make much sense, because @@ -425,8 +423,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, max_sectors=max_sectors, overwrite_only=overwrite_only, endian=endian, load_addr=load_addr, rom_fixed=rom_fixed, erased_val=erased_val, save_enctlv=save_enctlv, - security_counter=security_counter, max_align=max_align, - non_bootable=non_bootable) + security_counter=security_counter, max_align=max_align) img.load(infile) key = load_key(key) if key else None enckey = load_key(encrypt) if encrypt else None From ffa22ae64e45d898fe6419f2b7734997adba5659 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 116/238] Revert "[nrf fromtree] imgtool: Fix verify command for edcsa-p384 signed images" This reverts commit 5e33dacb69c7989e5fe07646d7c14c9b4d49e77b. --- scripts/imgtool/image.py | 101 +++++++++++++++++---------------------- scripts/imgtool/main.py | 2 - 2 files changed, 45 insertions(+), 58 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index a30d53bf2..3de8357a6 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -1,6 +1,6 @@ # Copyright 2018 Nordic Semiconductor ASA # Copyright 2017-2020 Linaro Limited -# Copyright 2019-2024 Arm Limited +# Copyright 2019-2023 Arm Limited # # SPDX-License-Identifier: Apache-2.0 # @@ -20,25 +20,23 @@ Image signing and management. """ +from . import version as versmod +from .boot_record import create_sw_component_data +import click +from enum import Enum +from intelhex import IntelHex import hashlib -import os.path import struct -from enum import Enum - -import click -from cryptography.exceptions import InvalidSignature -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import hashes, hmac +import os.path +from .keys import rsa, ecdsa, x25519 from cryptography.hazmat.primitives.asymmetric import ec, padding from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives.kdf.hkdf import HKDF from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat -from intelhex import IntelHex - -from . import version as versmod, keys -from .boot_record import create_sw_component_data -from .keys import rsa, ecdsa, x25519 +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes, hmac +from cryptography.exceptions import InvalidSignature IMAGE_MAGIC = 0x96f3b83d IMAGE_HEADER_SIZE = 32 @@ -92,8 +90,10 @@ } VerifyResult = Enum('VerifyResult', - ['OK', 'INVALID_MAGIC', 'INVALID_TLV_INFO_MAGIC', 'INVALID_HASH', 'INVALID_SIGNATURE', - 'KEY_MISMATCH']) + """ + OK INVALID_MAGIC INVALID_TLV_INFO_MAGIC INVALID_HASH + INVALID_SIGNATURE + """) def align_up(num, align): @@ -135,24 +135,7 @@ def get(self): return header + bytes(self.buf) -def get_digest(tlv_type, hash_region): - if tlv_type == TLV_VALUES["SHA384"]: - sha = hashlib.sha384() - elif tlv_type == TLV_VALUES["SHA256"]: - sha = hashlib.sha256() - - sha.update(hash_region) - return sha.digest() - - -def tlv_matches_key_type(tlv_type, key): - """Check if provided key matches to TLV record in the image""" - return (key is None or - type(key) == keys.ECDSA384P1 and tlv_type == TLV_VALUES["SHA384"] or - type(key) != keys.ECDSA384P1 and tlv_type == TLV_VALUES["SHA256"]) - - -class Image: +class Image(): def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, pad_header=False, pad=False, confirm=False, align=1, @@ -195,9 +178,9 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, msb = (self.max_align & 0xff00) >> 8 align = bytes([msb, lsb]) if self.endian == "big" else bytes([lsb, msb]) self.boot_magic = align + bytes([0x2d, 0xe1, - 0x5d, 0x29, 0x41, 0x0b, - 0x8d, 0x77, 0x67, 0x9c, - 0x11, 0x0f, 0x1f, 0x8a, ]) + 0x5d, 0x29, 0x41, 0x0b, + 0x8d, 0x77, 0x67, 0x9c, + 0x11, 0x0f, 0x1f, 0x8a, ]) if security_counter == 'auto': # Security counter has not been explicitly provided, @@ -338,8 +321,9 @@ def create(self, key, public_key_format, enckey, dependencies=None, self.enckey = enckey # Check what hashing algorithm should be used - if (key and isinstance(key, ecdsa.ECDSA384P1) - or pub_key and isinstance(pub_key, ecdsa.ECDSA384P1Public)): + if (key is not None and isinstance(key, ecdsa.ECDSA384P1) or + pub_key is not None and isinstance(pub_key, + ecdsa.ECDSA384P1Public)): hash_algorithm = hashlib.sha384 hash_tlv = "SHA384" else: @@ -446,13 +430,13 @@ def create(self, key, public_key_format, enckey, dependencies=None, if dependencies is not None: for i in range(dependencies_num): payload = struct.pack( - e + 'B3x' + 'BBHI', - int(dependencies[DEP_IMAGES_KEY][i]), - dependencies[DEP_VERSIONS_KEY][i].major, - dependencies[DEP_VERSIONS_KEY][i].minor, - dependencies[DEP_VERSIONS_KEY][i].revision, - dependencies[DEP_VERSIONS_KEY][i].build - ) + e + 'B3x'+'BBHI', + int(dependencies[DEP_IMAGES_KEY][i]), + dependencies[DEP_VERSIONS_KEY][i].major, + dependencies[DEP_VERSIONS_KEY][i].minor, + dependencies[DEP_VERSIONS_KEY][i].revision, + dependencies[DEP_VERSIONS_KEY][i].build + ) prot_tlv.add('DEPENDENCY', payload) if custom_tlvs is not None: @@ -656,37 +640,42 @@ def verify(imgfile, key): return VerifyResult.INVALID_MAGIC, None, None tlv_off = header_size + img_size - tlv_info = b[tlv_off:tlv_off + TLV_INFO_SIZE] + tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE] magic, tlv_tot = struct.unpack('HH', tlv_info) if magic == TLV_PROT_INFO_MAGIC: tlv_off += tlv_tot - tlv_info = b[tlv_off:tlv_off + TLV_INFO_SIZE] + tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE] magic, tlv_tot = struct.unpack('HH', tlv_info) if magic != TLV_INFO_MAGIC: return VerifyResult.INVALID_TLV_INFO_MAGIC, None, None + if isinstance(key, ecdsa.ECDSA384P1Public): + sha = hashlib.sha384() + hash_tlv = "SHA384" + else: + sha = hashlib.sha256() + hash_tlv = "SHA256" + prot_tlv_size = tlv_off - hash_region = b[:prot_tlv_size] - digest = None + sha.update(b[:prot_tlv_size]) + digest = sha.digest() + tlv_end = tlv_off + tlv_tot tlv_off += TLV_INFO_SIZE # skip tlv info while tlv_off < tlv_end: - tlv = b[tlv_off:tlv_off + TLV_SIZE] + tlv = b[tlv_off:tlv_off+TLV_SIZE] tlv_type, _, tlv_len = struct.unpack('BBH', tlv) - if tlv_type == TLV_VALUES["SHA256"] or tlv_type == TLV_VALUES["SHA384"]: - if not tlv_matches_key_type(tlv_type, key): - return VerifyResult.KEY_MISMATCH, None, None + if tlv_type == TLV_VALUES[hash_tlv]: off = tlv_off + TLV_SIZE - digest = get_digest(tlv_type, hash_region) - if digest == b[off:off + tlv_len]: + if digest == b[off:off+tlv_len]: if key is None: return VerifyResult.OK, version, digest else: return VerifyResult.INVALID_HASH, None, None elif key is not None and tlv_type == TLV_VALUES[key.sig_tlv()]: off = tlv_off + TLV_SIZE - tlv_sig = b[off:off + tlv_len] + tlv_sig = b[off:off+tlv_len] payload = b[:prot_tlv_size] try: if hasattr(key, 'verify'): diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index f70a8bf51..e24c9a087 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -228,8 +228,6 @@ def verify(key, imgfile): print("Image has an invalid hash") elif ret == image.VerifyResult.INVALID_SIGNATURE: print("No signature found for the given key") - elif ret == image.VerifyResult.KEY_MISMATCH: - print("Key type does not match TLV record") else: print("Unknown return code: {}".format(ret)) sys.exit(1) From c2b623182a71c384e15d6d4f53610200ba03f448 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 117/238] Revert "[nrf noup] boot: Add shared crypto for ECDSA and SHA" This reverts commit c2ff45bea3c052605f04793a41e043f5512d3af2. --- boot/bootutil/include/bootutil/crypto/ecdsa.h | 64 ++----------------- boot/bootutil/include/bootutil/crypto/sha.h | 32 ---------- boot/zephyr/CMakeLists.txt | 2 - boot/zephyr/external_crypto.conf | 20 ------ .../include/mcuboot_config/mcuboot_config.h | 5 +- 5 files changed, 9 insertions(+), 114 deletions(-) delete mode 100644 boot/zephyr/external_crypto.conf diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index 450450dc3..5a87f736b 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -34,7 +34,6 @@ #if (defined(MCUBOOT_USE_TINYCRYPT) + \ defined(MCUBOOT_USE_CC310) + \ - defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_PSA_OR_MBED_TLS)) != 1 #error "One crypto backend must be defined: either CC310/TINYCRYPT/MBED_TLS/PSA_CRYPTO" #endif @@ -71,18 +70,12 @@ #include "bootutil/sign_key.h" #include "common.h" -#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) - #include - #define NUM_ECC_BYTES (256 / 8) -#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ - #ifdef __cplusplus extern "C" { #endif #if (defined(MCUBOOT_USE_TINYCRYPT) || defined(MCUBOOT_USE_MBED_TLS) || \ - defined(MCUBOOT_USE_CC310) || defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO)) \ - && !defined(MCUBOOT_USE_PSA_CRYPTO) + defined(MCUBOOT_USE_CC310)) && !defined(MCUBOOT_USE_PSA_CRYPTO) /* * Declaring these like this adds NULL termination. */ @@ -134,6 +127,8 @@ static int bootutil_import_key(uint8_t **cp, uint8_t *end) } #endif /* (MCUBOOT_USE_TINYCRYPT || MCUBOOT_USE_MBED_TLS || MCUBOOT_USE_CC310) && !MCUBOOT_USE_PSA_CRYPTO */ +#if defined(MCUBOOT_USE_TINYCRYPT) +#ifndef MCUBOOT_ECDSA_NEED_ASN1_SIG /* * cp points to ASN1 string containing an integer. * Verify the tag, and that the length is 32 bytes. Helper function. @@ -183,8 +178,8 @@ static int bootutil_decode_sig(uint8_t signature[NUM_ECC_BYTES * 2], uint8_t *cp } return 0; } +#endif /* not MCUBOOT_ECDSA_NEED_ASN1_SIG */ -#if defined(MCUBOOT_USE_TINYCRYPT) typedef uintptr_t bootutil_ecdsa_context; static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) { @@ -253,12 +248,8 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, { (void)ctx; (void)pk_len; + (void)sig_len; (void)hash_len; - uint8_t dsig[2 * NUM_ECC_BYTES]; - - if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { - return -1; - } /* Only support uncompressed keys. */ if (pk[0] != 0x04) { @@ -266,7 +257,7 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, } pk++; - return cc310_ecdsa_verify_secp256r1(hash, pk, dsig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); + return cc310_ecdsa_verify_secp256r1(hash, pk, sig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); } static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, @@ -622,49 +613,6 @@ static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, #endif /* MCUBOOT_USE_MBED_TLS */ -#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) -typedef uintptr_t bootutil_ecdsa_context; -static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) -{ - (void)ctx; -} - -static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx) -{ - (void)ctx; -} - -static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, - uint8_t *pk, size_t pk_len, - uint8_t *hash, size_t hash_len, - uint8_t *sig, size_t sig_len) -{ - (void)ctx; - (void)pk_len; - (void)hash_len; - uint8_t dsig[2 * NUM_ECC_BYTES]; - - if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { - return -1; - } - - /* Only support uncompressed keys. */ - if (pk[0] != 0x04) { - return -1; - } - pk++; - - return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, pk, dsig); -} - -static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, - uint8_t **cp,uint8_t *end) -{ - (void)ctx; - return bootutil_import_key(cp, end); -} -#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ - #ifdef __cplusplus } #endif diff --git a/boot/bootutil/include/bootutil/crypto/sha.h b/boot/bootutil/include/bootutil/crypto/sha.h index aeedff40e..28499ed6a 100644 --- a/boot/bootutil/include/bootutil/crypto/sha.h +++ b/boot/bootutil/include/bootutil/crypto/sha.h @@ -30,7 +30,6 @@ #if (defined(MCUBOOT_USE_PSA_OR_MBED_TLS) + \ defined(MCUBOOT_USE_TINYCRYPT) + \ - defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_CC310)) != 1 #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO" #endif @@ -214,37 +213,6 @@ static inline int bootutil_sha_finish(bootutil_sha_context *ctx, } #endif /* MCUBOOT_USE_CC310 */ -#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) - -#include - -typedef bl_sha256_ctx_t bootutil_sha_context; - -static inline void bootutil_sha_init(bootutil_sha_context *ctx) -{ - bl_sha256_init(ctx); -} - -static inline void bootutil_sha_drop(bootutil_sha_context *ctx) -{ - (void)ctx; -} - -static inline int bootutil_sha_update(bootutil_sha_context *ctx, - const void *data, - uint32_t data_len) -{ - return bl_sha256_update(ctx, data, data_len); -} - -static inline int bootutil_sha_finish(bootutil_sha_context *ctx, - uint8_t *output) -{ - bl_sha256_finalize(ctx, output); - return 0; -} -#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ - #ifdef __cplusplus } #endif diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index c26633d11..382c98d9e 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -171,8 +171,6 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) zephyr_library_sources(${MCUBOOT_NRF_EXT_DIR}/cc310_glue.c) zephyr_library_include_directories(${MCUBOOT_NRF_EXT_DIR}) zephyr_link_libraries(nrfxlib_crypto) - elseif(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) - zephyr_include_directories(${BL_CRYPTO_DIR}/../include) endif() # Since here we are not using Zephyr's mbedTLS but rather our own, we need diff --git a/boot/zephyr/external_crypto.conf b/boot/zephyr/external_crypto.conf deleted file mode 100644 index 8181ad51c..000000000 --- a/boot/zephyr/external_crypto.conf +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2021 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - -# These configurations should be used when using nrf/samples/bootloader -# as the immutable bootloader (B0), and MCUBoot as the second stage updateable -# bootloader. - -# Set ECDSA as signing mechanism -CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y - -# Use crypto backend from B0 -CONFIG_BOOT_NRF_EXTERNAL_CRYPTO=y -CONFIG_SECURE_BOOT_CRYPTO=y -CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y -CONFIG_SB_CRYPTO_CLIENT_SHA256=y -CONFIG_BL_SHA256_EXT_API_REQUIRED=y -CONFIG_BL_SECP256R1_EXT_API_REQUIRED=y diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 9d58436d2..49820ed7c 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -40,10 +40,11 @@ #define MCUBOOT_USE_TINYCRYPT #elif defined(CONFIG_BOOT_USE_CC310) #define MCUBOOT_USE_CC310 +#ifdef CONFIG_BOOT_USE_NRF_CC310_BL +#define MCUBOOT_USE_NRF_CC310_BL +#endif #elif defined(CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT) #define MCUBOOT_USE_PSA_CRYPTO -#elif defined(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) -#define MCUBOOT_USE_NRF_EXTERNAL_CRYPTO #endif #ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA512 From 7308a085a4fd617431b41935126aadd545509657 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 118/238] Revert "[nrf fromtree] boot: SHA512 verification" This reverts commit 2d66e666a0566843ef907035b8300af5608ca972. --- boot/bootutil/include/bootutil/crypto/sha.h | 15 ++--- boot/bootutil/include/bootutil/image.h | 1 - boot/bootutil/src/image_validate.c | 1 - boot/zephyr/Kconfig | 56 ------------------- .../include/mcuboot_config/mcuboot_config.h | 10 ---- 5 files changed, 4 insertions(+), 79 deletions(-) diff --git a/boot/bootutil/include/bootutil/crypto/sha.h b/boot/bootutil/include/bootutil/crypto/sha.h index 28499ed6a..9ce54bee5 100644 --- a/boot/bootutil/include/bootutil/crypto/sha.h +++ b/boot/bootutil/include/bootutil/crypto/sha.h @@ -34,16 +34,13 @@ #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO" #endif -#if defined(MCUBOOT_SHA512) - #define IMAGE_HASH_SIZE (64) - #define EXPECTED_HASH_TLV IMAGE_TLV_SHA512 -#elif defined(MCUBOOT_SIGN_EC384) +#if defined(MCUBOOT_SIGN_EC384) #define IMAGE_HASH_SIZE (48) #define EXPECTED_HASH_TLV IMAGE_TLV_SHA384 #else #define IMAGE_HASH_SIZE (32) #define EXPECTED_HASH_TLV IMAGE_TLV_SHA256 -#endif /* MCUBOOT_SIGN */ +#endif /* MCUBOOT_SIGN_EC384 */ /* Universal defines for SHA-256 */ #define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64) @@ -85,9 +82,7 @@ typedef psa_hash_operation_t bootutil_sha_context; static inline int bootutil_sha_init(bootutil_sha_context *ctx) { *ctx = psa_hash_operation_init(); -#if defined(MCUBOOT_SHA512) - psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_512); -#elif defined(MCUBOOT_SIGN_EC384) +#if defined(MCUBOOT_SIGN_EC384) psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_384); #else psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_256); @@ -112,9 +107,7 @@ static inline int bootutil_sha_finish(bootutil_sha_context *ctx, { size_t hash_length = 0; /* Assumes the output buffer is at least the expected size of the hash */ -#if defined(MCUBOOT_SHA512) - return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_512), &hash_length); -#elif defined(MCUBOOT_SIGN_EC384) +#if defined(MCUBOOT_SIGN_EC384) return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_384), &hash_length); #else return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_256), &hash_length); diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 9ede800a2..3e03f80dd 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -96,7 +96,6 @@ struct flash_area; #define IMAGE_TLV_PUBKEY 0x02 /* public key */ #define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */ #define IMAGE_TLV_SHA384 0x11 /* SHA384 of image hdr and body */ -#define IMAGE_TLV_SHA512 0x12 /* SHA512 of image hdr and body */ #define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */ #define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output - Not supported anymore */ #define IMAGE_TLV_ECDSA_SIG 0x22 /* ECDSA of hash output */ diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 5043d385a..81782edf2 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -368,7 +368,6 @@ static const uint16_t allowed_unprot_tlvs[] = { IMAGE_TLV_PUBKEY, IMAGE_TLV_SHA256, IMAGE_TLV_SHA384, - IMAGE_TLV_SHA512, IMAGE_TLV_RSA2048_PSS, IMAGE_TLV_ECDSA224, IMAGE_TLV_ECDSA_SIG, diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 8b35ab18c..28f40bf52 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -27,12 +27,6 @@ config BOOT_USE_MBEDTLS help Use mbedTLS for crypto primitives. -config BOOT_USE_PSA_CRYPTO - bool - # Hidden option - help - Hidden option set if using PSA crypt for cryptography functionality - config BOOT_USE_TINYCRYPT bool # Hidden option @@ -76,52 +70,6 @@ config SINGLE_APPLICATION_SLOT uploading a new application overwrites the one that previously occupied the area. -config BOOT_IMG_HASH_ALG_SHA256_ALLOW - bool - help - Hidden option set by configurations that allow SHA256 - -config BOOT_IMG_HASH_ALG_SHA384_ALLOW - bool - help - Hidden option set by configurations that allow SHA384 - -config BOOT_IMG_HASH_ALG_SHA512_ALLOW - bool - depends on BOOT_USE_PSA_CRYPTO - help - Hidden option set by configurations that allow SHA512 - -choice BOOT_IMG_HASH_ALG - prompt "Selected image hash algorithm" - default BOOT_IMG_HASH_ALG_SHA256 if BOOT_IMG_HASH_ALG_SHA256_ALLOW - default BOOT_IMG_HASH_ALG_SHA384 if BOOT_IMG_HASH_ALG_SHA384_ALLOW - default BOOT_IMG_HASH_ALG_SHA512 if BOOT_IMG_HASH_ALG_SHA512_ALLOW - help - Hash algorithm used for image verification. Selection - here may be limited by other configurations, like for - example selected cryptographic signature. - -config BOOT_IMG_HASH_ALG_SHA256 - bool "SHA256" - depends on BOOT_IMG_HASH_ALG_SHA256_ALLOW - help - SHA256 algorithm - -config BOOT_IMG_HASH_ALG_SHA384 - bool "SHA384" - depends on BOOT_IMG_HASH_ALG_SHA384_ALLOW - help - SHA384 algorithm - -config BOOT_IMG_HASH_ALG_SHA512 - bool "SHA512" - depends on BOOT_IMG_HASH_ALG_SHA512_ALLOW - help - SHA512 algorithm - -endchoice # BOOT_IMG_HASH_ALG - choice BOOT_SIGNATURE_TYPE prompt "Signature type" default BOOT_SIGNATURE_TYPE_RSA @@ -129,14 +77,12 @@ choice BOOT_SIGNATURE_TYPE config BOOT_SIGNATURE_TYPE_NONE bool "No signature; use only hash check" select BOOT_USE_TINYCRYPT - select BOOT_IMG_HASH_ALG_SHA256_ALLOW config BOOT_SIGNATURE_TYPE_RSA bool "RSA signatures" select BOOT_USE_MBEDTLS select MBEDTLS select BOOT_ENCRYPTION_SUPPORT - select BOOT_IMG_HASH_ALG_SHA256_ALLOW if BOOT_SIGNATURE_TYPE_RSA config BOOT_SIGNATURE_TYPE_RSA_LEN @@ -148,7 +94,6 @@ endif config BOOT_SIGNATURE_TYPE_ECDSA_P256 bool "Elliptic curve digital signatures with curve P-256" select BOOT_ENCRYPTION_SUPPORT - select BOOT_IMG_HASH_ALG_SHA256_ALLOW if BOOT_SIGNATURE_TYPE_ECDSA_P256 choice BOOT_ECDSA_IMPLEMENTATION @@ -172,7 +117,6 @@ endif config BOOT_SIGNATURE_TYPE_ED25519 bool "Edwards curve digital signatures using ed25519" select BOOT_ENCRYPTION_SUPPORT - select BOOT_IMG_HASH_ALG_SHA256_ALLOW if BOOT_SIGNATURE_TYPE_ED25519 choice BOOT_ED25519_IMPLEMENTATION diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 49820ed7c..2f0cc243c 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -43,16 +43,6 @@ #ifdef CONFIG_BOOT_USE_NRF_CC310_BL #define MCUBOOT_USE_NRF_CC310_BL #endif -#elif defined(CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT) -#define MCUBOOT_USE_PSA_CRYPTO -#endif - -#ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA512 -#define MCUBOOT_SHA512 -#endif - -#ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA256 -#define MCUBOOT_SHA256 #endif /* Zephyr, regardless of C library used, provides snprintf */ From 031671df41693f19967e9186aeeef1e9fee70e39 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 119/238] Revert "[nrf noup] zephyr: Add support for compressed image updates" This reverts commit 92121b1e20347ebd057e55a3e86e5774f6e32d04. --- boot/bootutil/src/image_validate.c | 224 ---- boot/bootutil/src/loader.c | 102 +- boot/zephyr/CMakeLists.txt | 6 - boot/zephyr/Kconfig | 5 - boot/zephyr/decompression.c | 1105 ----------------- .../include/compression/decompression.h | 104 -- 6 files changed, 21 insertions(+), 1525 deletions(-) delete mode 100644 boot/zephyr/decompression.c delete mode 100644 boot/zephyr/include/compression/decompression.h diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 81782edf2..a697676b6 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -40,15 +40,6 @@ #include "mcuboot_config/mcuboot_config.h" -#if defined(MCUBOOT_DECOMPRESS_IMAGES) -#include -#include -#endif - -#include "bootutil/bootutil_log.h" - -BOOT_LOG_MODULE_DECLARE(mcuboot); - #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" #endif @@ -421,66 +412,6 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, FIH_DECLARE(security_counter_valid, FIH_FAILURE); #endif -#ifdef MCUBOOT_DECOMPRESS_IMAGES - /* If the image is compressed, the integrity of the image must also be validated */ - if (MUST_DECOMPRESS(fap, image_index, hdr)) { - bool found_decompressed_size = false; - bool found_decompressed_sha = false; - bool found_decompressed_signature = false; - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, true); - if (rc) { - goto out; - } - - if (it.tlv_end > bootutil_max_image_size(fap)) { - rc = -1; - goto out; - } - - while (true) { - uint16_t expected_size = 0; - bool *found_flag = NULL; - - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - break; - } - - switch (type) { - case IMAGE_TLV_DECOMP_SIZE: - expected_size = sizeof(size_t); - found_flag = &found_decompressed_size; - break; - case IMAGE_TLV_DECOMP_SHA: - expected_size = IMAGE_HASH_SIZE; - found_flag = &found_decompressed_sha; - break; - case IMAGE_TLV_DECOMP_SIGNATURE: - expected_size = SIG_BUF_SIZE; - found_flag = &found_decompressed_signature; - break; - default: - continue; - }; - - if (len != expected_size) { - rc = -1; - goto out; - } - - *found_flag = true; - } - - rc = (!found_decompressed_size || !found_decompressed_sha || !found_decompressed_signature); - if (rc) { - goto out; - } - } -#endif - rc = bootutil_img_hash(enc_state, image_index, hdr, fap, tmp_buf, tmp_buf_sz, hash, seed, seed_len); if (rc) { @@ -652,161 +583,6 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } #endif -#ifdef MCUBOOT_DECOMPRESS_IMAGES - /* Only after all previous verifications have passed, perform a dry-run of the decompression - * and ensure the image is valid - */ - if (!rc && MUST_DECOMPRESS(fap, image_index, hdr)) { - image_hash_valid = 0; - FIH_SET(valid_signature, FIH_FAILURE); - - rc = bootutil_img_hash_decompress(enc_state, image_index, hdr, fap, tmp_buf, tmp_buf_sz, - hash, seed, seed_len); - if (rc) { - goto out; - } - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SHA, true); - if (rc) { - goto out; - } - - if (it.tlv_end > bootutil_max_image_size(fap)) { - rc = -1; - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - break; - } - - if (type == IMAGE_TLV_DECOMP_SHA) { - /* Verify the image hash. This must always be present. */ - if (len != sizeof(hash)) { - rc = -1; - goto out; - } - rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, sizeof(hash)); - if (rc) { - goto out; - } - - FIH_CALL(boot_fih_memequal, fih_rc, hash, buf, sizeof(hash)); - if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { - FIH_SET(fih_rc, FIH_FAILURE); - goto out; - } - - image_hash_valid = 1; - } - } - - rc = !image_hash_valid; - if (rc) { - goto out; - } - -#ifdef EXPECTED_SIG_TLV -#ifdef EXPECTED_KEY_TLV - rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_KEY_TLV, false); - if (rc) { - goto out; - } - - if (it.tlv_end > bootutil_max_image_size(fap)) { - rc = -1; - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - break; - } - - if (type == EXPECTED_KEY_TLV) { - /* - * Determine which key we should be checking. - */ - if (len > KEY_BUF_SIZE) { - rc = -1; - goto out; - } -#ifndef MCUBOOT_HW_KEY - rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, len); - if (rc) { - goto out; - } - key_id = bootutil_find_key(buf, len); -#else - rc = LOAD_IMAGE_DATA(hdr, fap, off, key_buf, len); - if (rc) { - goto out; - } - key_id = bootutil_find_key(image_index, key_buf, len); -#endif /* !MCUBOOT_HW_KEY */ - /* - * The key may not be found, which is acceptable. There - * can be multiple signatures, each preceded by a key. - */ - } - } -#endif /* EXPECTED_KEY_TLV */ - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIGNATURE, true); - if (rc) { - goto out; - } - - if (it.tlv_end > bootutil_max_image_size(fap)) { - rc = -1; - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } - - if (type == IMAGE_TLV_DECOMP_SIGNATURE) { - /* Ignore this signature if it is out of bounds. */ - if (key_id < 0 || key_id >= bootutil_key_cnt) { - key_id = -1; - continue; - } - - if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) { - rc = -1; - goto out; - } - rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, len); - if (rc) { - goto out; - } - - FIH_CALL(bootutil_verify_sig, valid_signature, hash, sizeof(hash), - buf, len, key_id); - key_id = -1; - } - } -#endif /* EXPECTED_SIG_TLV */ - } -#endif - -#ifdef EXPECTED_SIG_TLV - FIH_SET(fih_rc, valid_signature); -#endif - out: if (rc) { FIH_SET(fih_rc, FIH_FAILURE); diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index d35b6910c..22485861e 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,11 +49,6 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" -#if defined(MCUBOOT_DECOMPRESS_IMAGES) -#include -#include -#endif - #ifdef __ZEPHYR__ #include #endif @@ -576,76 +571,35 @@ boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size) goto done; } -#ifdef MCUBOOT_DECOMPRESS_IMAGES - if (MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), boot_img_hdr(state, slot))) { - uint32_t tmp_size = 0; - - rc = bootutil_get_img_decomp_size(boot_img_hdr(state, slot), fap, &tmp_size); - - if (rc) { - rc = BOOT_EBADIMAGE; - goto done; - } - - off = boot_img_hdr(state, slot)->ih_hdr_size + tmp_size; - - rc = boot_size_protected_tlvs(boot_img_hdr(state, slot), fap, &tmp_size); - - if (rc) { - rc = BOOT_EBADIMAGE; - goto done; - } - - off += tmp_size; + off = BOOT_TLV_OFF(boot_img_hdr(state, slot)); - if (flash_area_read(fap, (BOOT_TLV_OFF(boot_img_hdr(state, slot)) + - boot_img_hdr(state, slot)->ih_protect_tlv_size), &info, - sizeof(info))) { - rc = BOOT_EFLASH; - goto done; - } + if (flash_area_read(fap, off, &info, sizeof(info))) { + rc = BOOT_EFLASH; + goto done; + } - if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { + protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size; + if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { + if (protect_tlv_size != info.it_tlv_tot) { rc = BOOT_EBADIMAGE; goto done; } - *size = off + info.it_tlv_tot; - } else { -#else - if (1) { -#endif - off = BOOT_TLV_OFF(boot_img_hdr(state, slot)); - - if (flash_area_read(fap, off, &info, sizeof(info))) { + if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) { rc = BOOT_EFLASH; goto done; } + } else if (protect_tlv_size != 0) { + rc = BOOT_EBADIMAGE; + goto done; + } - protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size; - if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { - if (protect_tlv_size != info.it_tlv_tot) { - rc = BOOT_EBADIMAGE; - goto done; - } - - if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) { - rc = BOOT_EFLASH; - goto done; - } - } else if (protect_tlv_size != 0) { - rc = BOOT_EBADIMAGE; - goto done; - } - - if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { - rc = BOOT_EBADIMAGE; - goto done; - } - - *size = off + protect_tlv_size + info.it_tlv_tot; + if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { + rc = BOOT_EBADIMAGE; + goto done; } + *size = off + protect_tlv_size + info.it_tlv_tot; rc = 0; done: @@ -974,10 +928,10 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa return false; } #else - if (MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), hdr)) { - if (!boot_is_compressed_header_valid(hdr, fap, state)) { - return false; - } + if ((hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1) && + (hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) + { + return false; } #endif @@ -1157,7 +1111,6 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * attempts to validate and boot it. */ } - #if !defined(__BOOTSIM__) BOOT_LOG_ERR("Image in the %s slot is not valid!", (slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary"); @@ -1581,9 +1534,6 @@ boot_copy_region(struct boot_loader_state *state, uint32_t blk_sz; uint8_t image_index; #endif -#ifdef MCUBOOT_DECOMPRESS_IMAGES - struct image_header *hdr; -#endif TARGET_STATIC uint8_t buf[BUF_SZ] __attribute__((aligned(4))); @@ -1591,16 +1541,6 @@ boot_copy_region(struct boot_loader_state *state, (void)state; #endif -#ifdef MCUBOOT_DECOMPRESS_IMAGES - hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); - - if (MUST_DECOMPRESS(fap_src, BOOT_CURR_IMG(state), hdr)) { - /* Use alternative function for compressed images */ - return boot_copy_region_decompress(state, fap_src, fap_dst, off_src, off_dst, sz, buf, - BUF_SZ); - } -#endif - bytes_copied = 0; while (bytes_copied < sz) { if (sz - bytes_copied > sizeof buf) { diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 382c98d9e..f26b090a6 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -249,12 +249,6 @@ if(CONFIG_BOOT_ENCRYPT_EC256) ) endif() -if(CONFIG_BOOT_DECOMPRESSION) - zephyr_library_sources( - decompression.c - ) -endif() - if(CONFIG_MCUBOOT_SERIAL) zephyr_sources(${BOOT_DIR}/zephyr/serial_adapter.c) zephyr_sources(${BOOT_DIR}/boot_serial/src/boot_serial.c) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 28f40bf52..2dbfc3135 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -723,10 +723,6 @@ config BOOT_BANNER_STRING config BOOT_DECOMPRESSION_SUPPORT bool - depends on NRF_COMPRESS && NRF_COMPRESS_DECOMPRESSION && (NRF_COMPRESS_LZMA_VERSION_LZMA1 || NRF_COMPRESS_LZMA_VERSION_LZMA2) - depends on !SINGLE_APPLICATION_SLOT && !BOOT_ENCRYPT_IMAGE && BOOT_UPGRADE_ONLY - depends on UPDATEABLE_IMAGE_NUMBER = 1 - default y help Hidden symbol which should be selected if a system provided decompression support. @@ -734,7 +730,6 @@ if BOOT_DECOMPRESSION_SUPPORT menuconfig BOOT_DECOMPRESSION bool "Decompression" - select NRF_COMPRESS_CLEANUP help If enabled, will include support for compressed images being loaded to the secondary slot which then get decompressed into the primary slot. This mode allows the secondary slot to diff --git a/boot/zephyr/decompression.c b/boot/zephyr/decompression.c deleted file mode 100644 index 5d491adcf..000000000 --- a/boot/zephyr/decompression.c +++ /dev/null @@ -1,1105 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#include -#include "compression/decompression.h" -#include "bootutil/crypto/sha.h" -#include "bootutil/bootutil_log.h" - -#if !defined(__BOOTSIM__) -#define TARGET_STATIC static -#else -#define TARGET_STATIC -#endif - -#if defined(MCUBOOT_SIGN_RSA) -#if MCUBOOT_SIGN_RSA_LEN == 2048 -#define EXPECTED_SIG_TLV IMAGE_TLV_RSA2048_PSS -#elif MCUBOOT_SIGN_RSA_LEN == 3072 -#define EXPECTED_SIG_TLV IMAGE_TLV_RSA3072_PSS -#endif -#elif defined(MCUBOOT_SIGN_EC256) || \ - defined(MCUBOOT_SIGN_EC384) || \ - defined(MCUBOOT_SIGN_EC) -#define EXPECTED_SIG_TLV IMAGE_TLV_ECDSA_SIG -#elif defined(MCUBOOT_SIGN_ED25519) -#define EXPECTED_SIG_TLV IMAGE_TLV_ED25519 -#endif - -/* Number of times that consumed data by decompression system can be 0 in a row before aborting */ -#define OFFSET_ZERO_CHECK_TIMES 3 - -BOOT_LOG_MODULE_DECLARE(mcuboot); - -static int boot_sha_protected_tlvs(const struct image_header *hdr, - const struct flash_area *fap_src, uint32_t protected_size, - uint8_t *buf, size_t buf_size, bootutil_sha_context *sha_ctx); - -bool boot_is_compressed_header_valid(const struct image_header *hdr, const struct flash_area *fap, - struct boot_loader_state *state) -{ - /* Image is compressed in secondary slot, need to check if fits into the primary slot */ - bool opened_flash_area = false; - int primary_fa_id; - int rc; - int size_check; - int size; - uint32_t protected_tlvs_size; - uint32_t decompressed_size; - - if (BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT) == NULL) { - opened_flash_area = true; - } - - primary_fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT); - rc = flash_area_open(primary_fa_id, &BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); - assert(rc == 0); - - size_check = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); - - if (opened_flash_area) { - (void)flash_area_close(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); - } - - rc = bootutil_get_img_decomp_size(hdr, fap, &decompressed_size); - - if (rc) { - return false; - } - - if (!boot_u32_safe_add(&size, decompressed_size, hdr->ih_hdr_size)) { - return false; - } - - rc = boot_size_protected_tlvs(hdr, fap, &protected_tlvs_size); - - if (rc) { - return false; - } - - if (!boot_u32_safe_add(&size, size, protected_tlvs_size)) { - return false; - } - - if (size >= size_check) { - BOOT_LOG_ERR("Compressed image too large, decompressed image size: 0x%x, slot size: 0x%x", - size, size_check); - - return false; - } - - return true; -} - -int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index, - struct image_header *hdr, const struct flash_area *fap, - uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result, - uint8_t *seed, int seed_len) -{ - int rc; - uint32_t read_pos = 0; - uint32_t write_pos = 0; - uint32_t protected_tlv_size = 0; - uint32_t decompressed_image_size; - struct nrf_compress_implementation *compression = NULL; - TARGET_STATIC struct image_header modified_hdr; - bootutil_sha_context sha_ctx; - uint8_t flash_erased_value; - - bootutil_sha_init(&sha_ctx); - - /* Setup decompression system */ -#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 - if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) { -#elif CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 - if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) { -#endif - /* Compressed image does not use the correct compression type which is supported by this - * build - */ - BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); - rc = BOOT_EBADIMAGE; - - goto finish_without_clean; - } - - compression = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); - - if (compression == NULL || compression->init == NULL || compression->deinit == NULL || - compression->decompress_bytes_needed == NULL || compression->decompress == NULL) { - /* Compression library missing or missing required function pointer */ - BOOT_LOG_ERR("Decompression library fatal error"); - rc = BOOT_EBADSTATUS; - - goto finish_without_clean; - } - - rc = compression->init(NULL); - - if (rc) { - BOOT_LOG_ERR("Decompression library fatal error"); - rc = BOOT_EBADSTATUS; - - goto finish_without_clean; - } - - /* We need a modified header which has the updated sizes, start with the original header */ - memcpy(&modified_hdr, hdr, sizeof(modified_hdr)); - - /* Extract the decompressed image size from the protected TLV, set it and remove the - * compressed image flags - */ - rc = bootutil_get_img_decomp_size(hdr, fap, &decompressed_image_size); - - if (rc) { - BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); - rc = BOOT_EBADIMAGE; - - goto finish; - } - - modified_hdr.ih_flags &= ~COMPRESSIONFLAGS; - modified_hdr.ih_img_size = decompressed_image_size; - - /* Calculate the protected TLV size, these will not include the decompressed - * sha/size/signature entries - */ - rc = boot_size_protected_tlvs(hdr, fap, &protected_tlv_size); - - if (rc) { - BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); - rc = BOOT_EBADIMAGE; - - goto finish; - } - - modified_hdr.ih_protect_tlv_size = protected_tlv_size; - bootutil_sha_update(&sha_ctx, &modified_hdr, sizeof(modified_hdr)); - read_pos = sizeof(modified_hdr); - flash_erased_value = flash_area_erased_val(fap); - memset(tmp_buf, flash_erased_value, tmp_buf_sz); - - while (read_pos < modified_hdr.ih_hdr_size) { - uint32_t copy_size = tmp_buf_sz; - - if ((read_pos + copy_size) > modified_hdr.ih_hdr_size) { - copy_size = modified_hdr.ih_hdr_size - read_pos; - } - - bootutil_sha_update(&sha_ctx, tmp_buf, copy_size); - read_pos += copy_size; - } - - /* Read in compressed data, decompress and add to hash calculation */ - read_pos = 0; - - while (read_pos < hdr->ih_img_size) { - uint32_t copy_size = hdr->ih_img_size - read_pos; - uint32_t tmp_off = 0; - uint8_t offset_zero_check = 0; - - if (copy_size > tmp_buf_sz) { - copy_size = tmp_buf_sz; - } - - rc = flash_area_read(fap, (hdr->ih_hdr_size + read_pos), tmp_buf, copy_size); - - if (rc != 0) { - BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (hdr->ih_hdr_size + read_pos), copy_size, fap->fa_id, rc); - rc = BOOT_EFLASH; - - goto finish; - } - - /* Decompress data in chunks, writing it back with a larger write offset of the primary - * slot than read size of the secondary slot - */ - while (tmp_off < copy_size) { - uint32_t offset = 0; - uint8_t *output = NULL; - uint32_t output_size = 0; - uint32_t chunk_size; - bool last_packet = false; - - chunk_size = compression->decompress_bytes_needed(NULL); - - if (chunk_size > (copy_size - tmp_off)) { - chunk_size = (copy_size - tmp_off); - } - - if ((read_pos + tmp_off + chunk_size) >= hdr->ih_img_size) { - last_packet = true; - } - - rc = compression->decompress(NULL, &tmp_buf[tmp_off], chunk_size, last_packet, &offset, - &output, &output_size); - - if (rc) { - BOOT_LOG_ERR("Decompression error: %d", rc); - rc = BOOT_EBADSTATUS; - - goto finish; - } - - write_pos += output_size; - - if (write_pos > decompressed_image_size) { - BOOT_LOG_ERR("Decompressed image larger than claimed TLV size, at least: %d", - write_pos); - rc = BOOT_EBADIMAGE; - - goto finish; - } - - /* Additional dry-run validity checks */ - if (last_packet == true && write_pos == 0) { - /* Last packet and we still have no output, this is a faulty update */ - BOOT_LOG_ERR("All compressed data consumed without any output, image not valid"); - rc = BOOT_EBADIMAGE; - - goto finish; - } - - if (offset == 0) { - /* If the decompression system continually consumes 0 bytes, then there is a - * problem with this update image, abort and mark image as bad - */ - if (offset_zero_check >= OFFSET_ZERO_CHECK_TIMES) { - BOOT_LOG_ERR("Decompression system returning no output data, image not valid"); - rc = BOOT_EBADIMAGE; - - goto finish; - } - - ++offset_zero_check; - - break; - } else { - offset_zero_check = 0; - } - - if (output_size > 0) { - bootutil_sha_update(&sha_ctx, output, output_size); - } - - tmp_off += offset; - } - - read_pos += copy_size; - } - - /* If there are any protected TLVs present, add them after the main decompressed image */ - if (modified_hdr.ih_protect_tlv_size > 0) { - rc = boot_sha_protected_tlvs(hdr, fap, modified_hdr.ih_protect_tlv_size, tmp_buf, - tmp_buf_sz, &sha_ctx); - } - - bootutil_sha_finish(&sha_ctx, hash_result); - -finish: - /* Clean up decompression system */ - (void)compression->deinit(NULL); - -finish_without_clean: - bootutil_sha_drop(&sha_ctx); - - return rc; -} - -static int boot_copy_protected_tlvs(const struct image_header *hdr, - const struct flash_area *fap_src, - const struct flash_area *fap_dst, uint32_t off_dst, - uint32_t protected_size, uint8_t *buf, size_t buf_size, - uint16_t *buf_pos, uint32_t *written) -{ - int rc; - uint32_t off; - uint32_t write_pos = 0; - uint16_t len; - uint16_t type; - struct image_tlv_iter it; - struct image_tlv tlv_header; - struct image_tlv_info tlv_info_header = { - .it_magic = IMAGE_TLV_PROT_INFO_MAGIC, - .it_tlv_tot = protected_size, - }; - uint16_t info_size_left = sizeof(tlv_info_header); - - while (info_size_left > 0) { - uint16_t copy_size = buf_size - *buf_pos; - - if (info_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - uint8_t *tlv_info_header_address = (uint8_t *)&tlv_info_header; - - if (single_copy_size > info_size_left) { - single_copy_size = info_size_left; - } - - memcpy(&buf[*buf_pos], &tlv_info_header_address[sizeof(tlv_info_header) - - info_size_left], single_copy_size); - *buf_pos += single_copy_size; - info_size_left -= single_copy_size; - } - - if (*buf_pos == buf_size) { - rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); - - if (rc != 0) { - BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - - goto out; - } - - write_pos += *buf_pos; - *buf_pos = 0; - } - } - - rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, true); - - if (rc) { - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } - - if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || - type == IMAGE_TLV_DECOMP_SIGNATURE) { - /* Skip these TLVs as they are not needed */ - continue; - } else { - uint16_t header_size_left = sizeof(tlv_header); - uint16_t data_size_left = len; - - tlv_header.it_type = type; - tlv_header.it_len = len; - - while (header_size_left > 0 || data_size_left > 0) { - uint16_t copy_size = buf_size - *buf_pos; - uint8_t *tlv_header_address = (uint8_t *)&tlv_header; - - if (header_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - - if (single_copy_size > header_size_left) { - single_copy_size = header_size_left; - } - - memcpy(&buf[*buf_pos], &tlv_header_address[sizeof(tlv_header) - - header_size_left], - single_copy_size); - *buf_pos += single_copy_size; - copy_size -= single_copy_size; - header_size_left -= single_copy_size; - } - - if (data_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - - if (single_copy_size > data_size_left) { - single_copy_size = data_size_left; - } - - rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + (len - data_size_left)), - &buf[*buf_pos], single_copy_size); - - if (rc) { - BOOT_LOG_ERR( - "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); - - goto out; - } - - *buf_pos += single_copy_size; - data_size_left -= single_copy_size; - } - - if (*buf_pos == buf_size) { - rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); - - if (rc != 0) { - BOOT_LOG_ERR( - "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - - goto out; - } - - write_pos += *buf_pos; - *buf_pos = 0; - } - } - } - } - - *written = write_pos; - -out: - return rc; -} - -static int boot_sha_protected_tlvs(const struct image_header *hdr, - const struct flash_area *fap_src, uint32_t protected_size, - uint8_t *buf, size_t buf_size, bootutil_sha_context *sha_ctx) -{ - int rc; - uint32_t off; - uint16_t len; - uint16_t type; - struct image_tlv_iter it; - struct image_tlv tlv_header; - struct image_tlv_info tlv_info_header = { - .it_magic = IMAGE_TLV_PROT_INFO_MAGIC, - .it_tlv_tot = protected_size, - }; - - bootutil_sha_update(sha_ctx, &tlv_info_header, sizeof(tlv_info_header)); - - rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, true); - if (rc) { - goto out; - } - - while (true) { - uint32_t read_off = 0; - - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } - - if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || - type == IMAGE_TLV_DECOMP_SIGNATURE) { - /* Skip these TLVs as they are not needed */ - continue; - } - - tlv_header.it_type = type; - tlv_header.it_len = len; - - bootutil_sha_update(sha_ctx, &tlv_header, sizeof(tlv_header)); - - while (read_off < len) { - uint32_t copy_size = buf_size; - - if (copy_size > (len - read_off)) { - copy_size = len - read_off; - } - - rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + read_off), buf, copy_size); - - if (rc) { - BOOT_LOG_ERR( - "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off + read_off), copy_size, fap_src->fa_id, rc); - - goto out; - } - - bootutil_sha_update(sha_ctx, buf, copy_size); - read_off += copy_size; - } - } - -out: - return rc; -} - -int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_area *fap, - uint32_t *sz) -{ - int rc = 0; - uint32_t tlv_size; - uint32_t off; - uint16_t len; - uint16_t type; - struct image_tlv_iter it; - - *sz = 0; - tlv_size = hdr->ih_protect_tlv_size; - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, true); - - if (rc) { - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } - - if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || - type == IMAGE_TLV_DECOMP_SIGNATURE) { - /* Exclude these TLVs as they will be copied to the unprotected area */ - tlv_size -= len + sizeof(struct image_tlv); - } - } - - if (!rc) { - if (tlv_size == sizeof(struct image_tlv_info)) { - /* If there are no entries then omit protected TLV section entirely */ - tlv_size = 0; - } - - *sz = tlv_size; - } - -out: - return rc; -} - -int boot_size_unprotected_tlvs(const struct image_header *hdr, const struct flash_area *fap, - uint32_t *sz) -{ - int rc = 0; - uint32_t tlv_size; - uint32_t off; - uint16_t len; - uint16_t type; - struct image_tlv_iter it; - - *sz = 0; - tlv_size = sizeof(struct image_tlv_info); - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false); - - if (rc) { - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } else if (bootutil_tlv_iter_is_prot(&it, off)) { - continue; - } - - tlv_size += len + sizeof(struct image_tlv); - } - - if (!rc) { - if (tlv_size == sizeof(struct image_tlv_info)) { - /* If there are no entries in the unprotected TLV section then there is something wrong - * with this image - */ - BOOT_LOG_ERR("No unprotected TLVs in post-decompressed image output, image is invalid"); - rc = BOOT_EBADIMAGE; - - goto out; - } - - *sz = tlv_size; - } - -out: - return rc; -} - -static int boot_copy_unprotected_tlvs(const struct image_header *hdr, - const struct flash_area *fap_src, - const struct flash_area *fap_dst, uint32_t off_dst, - uint32_t unprotected_size, uint8_t *buf, size_t buf_size, - uint16_t *buf_pos, uint32_t *written) -{ - int rc; - uint32_t write_pos = 0; - uint32_t off; - uint16_t len; - uint16_t type; - struct image_tlv_iter it; - struct image_tlv_iter it_protected; - struct image_tlv tlv_header; - struct image_tlv_info tlv_info_header = { - .it_magic = IMAGE_TLV_INFO_MAGIC, - .it_tlv_tot = unprotected_size, - }; - uint16_t info_size_left = sizeof(tlv_info_header); - - while (info_size_left > 0) { - uint16_t copy_size = buf_size - *buf_pos; - - if (info_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - uint8_t *tlv_info_header_address = (uint8_t *)&tlv_info_header; - - if (single_copy_size > info_size_left) { - single_copy_size = info_size_left; - } - - memcpy(&buf[*buf_pos], &tlv_info_header_address[sizeof(tlv_info_header) - - info_size_left], single_copy_size); - *buf_pos += single_copy_size; - info_size_left -= single_copy_size; - } - - if (*buf_pos == buf_size) { - rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); - - if (rc != 0) { - BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - - goto out; - } - - write_pos += *buf_pos; - *buf_pos = 0; - } - } - - rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, false); - if (rc) { - goto out; - } - - while (true) { - uint16_t header_size_left = sizeof(tlv_header); - uint16_t data_size_left; - - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } else if (bootutil_tlv_iter_is_prot(&it, off)) { - /* Skip protected TLVs */ - continue; - } - - /* Change the values of these fields from having the data in the compressed image - * unprotected TLV (which is valid only for the compressed image data) to having the - * fields in the protected TLV section (which is valid for the decompressed image data). - * The compressed data is no longer needed - */ - if (type == EXPECTED_HASH_TLV || type == EXPECTED_SIG_TLV) { - rc = bootutil_tlv_iter_begin(&it_protected, hdr, fap_src, (type == EXPECTED_HASH_TLV ? - IMAGE_TLV_DECOMP_SHA : - IMAGE_TLV_DECOMP_SIGNATURE), - true); - - if (rc) { - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it_protected, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } - } - - if (type == IMAGE_TLV_DECOMP_SHA) { - type = EXPECTED_HASH_TLV; - } else { - type = EXPECTED_SIG_TLV; - } - } - - data_size_left = len; - tlv_header.it_type = type; - tlv_header.it_len = len; - - while (header_size_left > 0 || data_size_left > 0) { - uint16_t copy_size = buf_size - *buf_pos; - - if (header_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - uint8_t *tlv_header_address = (uint8_t *)&tlv_header; - - if (single_copy_size > header_size_left) { - single_copy_size = header_size_left; - } - - memcpy(&buf[*buf_pos], &tlv_header_address[sizeof(tlv_header) - header_size_left], - single_copy_size); - *buf_pos += single_copy_size; - copy_size -= single_copy_size; - header_size_left -= single_copy_size; - } - - if (data_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - - if (single_copy_size > data_size_left) { - single_copy_size = data_size_left; - } - - rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + len - data_size_left), - &buf[*buf_pos], single_copy_size); - - if (rc) { - BOOT_LOG_ERR( - "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); - - goto out; - } - - *buf_pos += single_copy_size; - data_size_left -= single_copy_size; - } - - if (*buf_pos == buf_size) { - rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); - - if (rc != 0) { - BOOT_LOG_ERR( - "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - - goto out; - } - - write_pos += *buf_pos; - *buf_pos = 0; - } - } - } - - *written = write_pos; - -out: - return rc; -} - -int boot_copy_region_decompress(struct boot_loader_state *state, const struct flash_area *fap_src, - const struct flash_area *fap_dst, uint32_t off_src, - uint32_t off_dst, uint32_t sz, uint8_t *buf, size_t buf_size) -{ - int rc; - uint32_t pos = 0; - uint16_t decomp_buf_size = 0; - uint16_t write_alignment; - uint32_t write_pos = 0; - uint32_t protected_tlv_size = 0; - uint32_t unprotected_tlv_size = 0; - uint32_t tlv_write_size = 0; - uint32_t decompressed_image_size; - struct nrf_compress_implementation *compression = NULL; - struct image_header *hdr; - TARGET_STATIC uint8_t decomp_buf[CONFIG_BOOT_DECOMPRESSION_BUFFER_SIZE] __attribute__((aligned(4))); - TARGET_STATIC struct image_header modified_hdr; - - hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); - - /* Setup decompression system */ -#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 - if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) { -#elif CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 - if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) { -#endif - /* Compressed image does not use the correct compression type which is supported by this - * build - */ - BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); - rc = BOOT_EBADIMAGE; - - goto finish; - } - - compression = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); - - if (compression == NULL || compression->init == NULL || compression->deinit == NULL || - compression->decompress_bytes_needed == NULL || compression->decompress == NULL) { - /* Compression library missing or missing required function pointer */ - BOOT_LOG_ERR("Decompression library fatal error"); - rc = BOOT_EBADSTATUS; - - goto finish; - } - - rc = compression->init(NULL); - - if (rc) { - BOOT_LOG_ERR("Decompression library fatal error"); - rc = BOOT_EBADSTATUS; - - goto finish; - } - - write_alignment = flash_area_align(fap_dst); - - memcpy(&modified_hdr, hdr, sizeof(modified_hdr)); - - rc = bootutil_get_img_decomp_size(hdr, fap_src, &decompressed_image_size); - - if (rc) { - BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); - rc = BOOT_EBADIMAGE; - - goto finish; - } - - modified_hdr.ih_flags &= ~COMPRESSIONFLAGS; - modified_hdr.ih_img_size = decompressed_image_size; - - /* Calculate protected TLV size for target image once items are removed */ - rc = boot_size_protected_tlvs(hdr, fap_src, &protected_tlv_size); - - if (rc) { - BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); - rc = BOOT_EBADIMAGE; - - goto finish; - } - - modified_hdr.ih_protect_tlv_size = protected_tlv_size; - - rc = boot_size_unprotected_tlvs(hdr, fap_src, &unprotected_tlv_size); - - if (rc) { - BOOT_LOG_ERR("Unable to determine unprotected TLV size of compressed image"); - rc = BOOT_EBADIMAGE; - - goto finish; - } - - /* Write out the image header first, this should be a multiple of the write size */ - rc = flash_area_write(fap_dst, off_dst, &modified_hdr, sizeof(modified_hdr)); - - if (rc != 0) { - BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - off_dst, sizeof(modified_hdr), fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - - goto finish; - } - - /* Read in, decompress and write out data */ - while (pos < hdr->ih_img_size) { - uint32_t copy_size = hdr->ih_img_size - pos; - uint32_t tmp_off = 0; - - if (copy_size > buf_size) { - copy_size = buf_size; - } - - rc = flash_area_read(fap_src, off_src + hdr->ih_hdr_size + pos, buf, copy_size); - - if (rc != 0) { - BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_src + hdr->ih_hdr_size + pos), copy_size, fap_src->fa_id, rc); - rc = BOOT_EFLASH; - - goto finish; - } - - /* Decompress data in chunks, writing it back with a larger write offset of the primary - * slot than read size of the secondary slot - */ - while (tmp_off < copy_size) { - uint32_t offset = 0; - uint32_t output_size = 0; - uint32_t chunk_size; - uint32_t compression_buffer_pos = 0; - uint8_t *output = NULL; - bool last_packet = false; - - chunk_size = compression->decompress_bytes_needed(NULL); - - if (chunk_size > (copy_size - tmp_off)) { - chunk_size = (copy_size - tmp_off); - } - - if ((pos + tmp_off + chunk_size) >= hdr->ih_img_size) { - last_packet = true; - } - - rc = compression->decompress(NULL, &buf[tmp_off], chunk_size, last_packet, &offset, - &output, &output_size); - - if (rc) { - BOOT_LOG_ERR("Decompression error: %d", rc); - rc = BOOT_EBADSTATUS; - - goto finish; - } - - /* Copy data to secondary buffer for writing out */ - while (output_size > 0) { - uint32_t data_size = (sizeof(decomp_buf) - decomp_buf_size); - - if (data_size > output_size) { - data_size = output_size; - } - - memcpy(&decomp_buf[decomp_buf_size], &output[compression_buffer_pos], data_size); - compression_buffer_pos += data_size; - - decomp_buf_size += data_size; - output_size -= data_size; - - /* Write data out from secondary buffer when it is full */ - if (decomp_buf_size == sizeof(decomp_buf)) { - rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), - decomp_buf, sizeof(decomp_buf)); - - if (rc != 0) { - BOOT_LOG_ERR( - "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + hdr->ih_hdr_size + write_pos), sizeof(decomp_buf), - fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - - goto finish; - } - - write_pos += sizeof(decomp_buf); - decomp_buf_size = 0; - } - } - - tmp_off += offset; - } - - pos += copy_size; - } - - /* Clean up decompression system */ - (void)compression->deinit(NULL); - - if (protected_tlv_size > 0) { - rc = boot_copy_protected_tlvs(hdr, fap_src, fap_dst, (off_dst + hdr->ih_hdr_size + - write_pos), protected_tlv_size, - decomp_buf, sizeof(decomp_buf_size), &decomp_buf_size, - &tlv_write_size); - - if (rc) { - BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); - - goto finish; - } - - write_pos += tlv_write_size; - } - - tlv_write_size = 0; - rc = boot_copy_unprotected_tlvs(hdr, fap_src, fap_dst, (off_dst + hdr->ih_hdr_size + - write_pos), unprotected_tlv_size, - decomp_buf, sizeof(decomp_buf_size), &decomp_buf_size, - &tlv_write_size); - - if (rc) { - BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); - - goto finish; - } - - write_pos += tlv_write_size; - - /* Check if we have unwritten data buffered up and, if so, write it out */ - if (decomp_buf_size > 0) { - uint32_t write_padding_size = decomp_buf_size % write_alignment; - - /* Check if additional write padding should be applied to meet the minimum write size */ - if (write_padding_size) { - uint8_t flash_erased_value; - - flash_erased_value = flash_area_erased_val(fap_dst); - memset(&decomp_buf[decomp_buf_size], flash_erased_value, write_padding_size); - decomp_buf_size += write_padding_size; - } - - rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), decomp_buf, - decomp_buf_size); - - if (rc != 0) { - BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + hdr->ih_hdr_size + write_pos), sizeof(decomp_buf_size), - fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - - goto finish; - } - - write_pos += decomp_buf_size; - decomp_buf_size = 0; - } - -finish: - memset(decomp_buf, 0, sizeof(decomp_buf)); - - return rc; -} - -int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct flash_area *fap, - uint32_t *img_decomp_size) -{ - struct image_tlv_iter it; - uint32_t off; - uint16_t len; - int32_t rc; - - if (hdr == NULL || fap == NULL || img_decomp_size == NULL) { - return BOOT_EBADARGS; - } else if (hdr->ih_protect_tlv_size == 0) { - return BOOT_EBADIMAGE; - } - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIZE, true); - - if (rc) { - return rc; - } - - rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); - - if (rc != 0) { - return -1; - } - - if (len != sizeof(*img_decomp_size)) { - BOOT_LOG_ERR("Invalid decompressed image size TLV: %d", len); - - return BOOT_EBADIMAGE; - } - - rc = LOAD_IMAGE_DATA(hdr, fap, off, img_decomp_size, len); - - if (rc) { - BOOT_LOG_ERR("Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - off, len, fap->fa_id, rc); - - return BOOT_EFLASH; - } - - return 0; -} diff --git a/boot/zephyr/include/compression/decompression.h b/boot/zephyr/include/compression/decompression.h deleted file mode 100644 index f8a676ac5..000000000 --- a/boot/zephyr/include/compression/decompression.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#ifndef H_DECOMPRESSION_ -#define H_DECOMPRESSION_ - -#include -#include -#include -#include "bootutil/bootutil.h" -#include "bootutil/bootutil_public.h" -#include "bootutil/image.h" -#include "../src/bootutil_priv.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Checks if a compressed image header is valid. - * - * @param hdr Image header. - * @param fap Flash area of the slot. - * @param state Bootloader state object. - * - * @return true if valid; false if invalid. - */ -bool boot_is_compressed_header_valid(const struct image_header *hdr, const struct flash_area *fap, - struct boot_loader_state *state); - -/** - * Reads in compressed image data from a slot, decompresses it and writes it out to a destination - * slot, including corresponding image headers and TLVs. - * - * @param state Bootloader state object. - * @param fap_src Flash area of the source slot. - * @param fap_dst Flash area of the destination slot. - * @param off_src Offset of the source slot to read from (should be 0). - * @param off_dst Offset of the destination slot to write to (should be 0). - * @param sz Size of the source slot data. - * @param buf Temporary buffer for reading data from. - * @param buf_size Size of temporary buffer. - * - * @return 0 on success; nonzero on failure. - */ -int boot_copy_region_decompress(struct boot_loader_state *state, const struct flash_area *fap_src, - const struct flash_area *fap_dst, uint32_t off_src, - uint32_t off_dst, uint32_t sz, uint8_t *buf, size_t buf_size); - -/** - * Gets the total data size (excluding headers and TLVs) of a compressed image when it is - * decompressed. - * - * @param hdr Image header. - * @param fap Flash area of the slot. - * @param img_decomp_size Pointer to variable that will be updated with the decompressed image - * size. - * - * @return 0 on success; nonzero on failure. - */ -int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct flash_area *fap, - uint32_t *img_decomp_size); - -/** - * Calculate MCUboot-compatible image hash of compressed image slot. - * - * @param enc_state Not currently used, set to NULL. - * @param image_index Image number. - * @param hdr Image header. - * @param fap Flash area of the slot. - * @param tmp_buf Temporary buffer for reading data from. - * @param tmp_buf_sz Size of temporary buffer. - * @param hash_result Pointer to a variable that will be updated with the image hash. - * @param seed Not currently used, set to NULL. - * @param seed_len Not currently used, set to 0. - * - * @return 0 on success; nonzero on failure. - */ -int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index, - struct image_header *hdr, const struct flash_area *fap, - uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result, - uint8_t *seed, int seed_len); - -/** - * Calculates the size that the compressed image protected TLV section will occupy once the image - * has been decompressed. - * - * @param hdr Image header. - * @param fap Flash area of the slot. - * @param sz Pointer to variable that will be updated with the protected TLV size. - * - * @return 0 on success; nonzero on failure. - */ -int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_area *fap_src, - uint32_t *sz); - -#ifdef __cplusplus -} -#endif - -#endif /* H_DECOMPRESSION_ */ From 86822739feeda18008bf6ab487ceda41df106c28 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 120/238] Revert "[nrf fromtree] docs: release-notes: Add note on changes" This reverts commit 5eaeac3e5ea0ba3c211f122013911c820ebc188f. --- docs/release-notes.d/zephyr-compression.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 docs/release-notes.d/zephyr-compression.md diff --git a/docs/release-notes.d/zephyr-compression.md b/docs/release-notes.d/zephyr-compression.md deleted file mode 100644 index ba9ec2a7a..000000000 --- a/docs/release-notes.d/zephyr-compression.md +++ /dev/null @@ -1,7 +0,0 @@ -- Added protected TLV size to image size check in bootutil -- Added Kconfig for decompression support in Zephyr -- Added compressed image flags and TLV to bootutil -- Added support for removing images with conflicting flags in - bootutil -- Added support for removing encrypted/compressed images when - MCUboot is compiled without support for them From 21442567b35ad69c5fc0b8904721cb90fcc031ce Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 121/238] Revert "[nrf fromtree] booutil: swap_scratch: Do not check sectors with compression" This reverts commit 21bac2b598e2bf8e91110f69127d55ae04c5202a. --- boot/bootutil/src/swap_scratch.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index 19be30c64..a32eb8d87 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -259,14 +259,12 @@ boot_slots_compatible(struct boot_loader_state *state) #endif } -#ifndef MCUBOOT_DECOMPRESS_IMAGES if ((i != num_sectors_primary) || (j != num_sectors_secondary) || (primary_slot_sz != secondary_slot_sz)) { BOOT_LOG_WRN("Cannot upgrade: slots are not compatible"); return 0; } -#endif return 1; #endif /* PM_S1_ADDRESS */ From f30510b2c95df968681d819cb5facc969919ad0c Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 122/238] Revert "[nrf fromtree] bootutil: loader: Add protected TLV size to image size check" This reverts commit 7d67371134426c56d2312fd979c9c13a2ade8e78. --- boot/bootutil/src/loader.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 22485861e..fb0551a74 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -897,16 +897,6 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa return false; } -#ifdef MCUBOOT_DECOMPRESS_IMAGES - if (!MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), hdr)) { -#else - if (1) { -#endif - if (!boot_u32_safe_add(&size, size, hdr->ih_protect_tlv_size)) { - return false; - } - } - if (size >= flash_area_get_size(fap)) { return false; } From 4b1c47d70d478bb64be4655a79a5c98e88e63e70 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 123/238] Revert "[nrf fromtree] bootutil: loader: Remove images with conflicting flags" This reverts commit cd557e1c4e3c11977aa34de0171a128275598cd8. --- boot/bootutil/src/loader.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index fb0551a74..5566f005e 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -905,24 +905,12 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa if (IS_ENCRYPTED(hdr)) { return false; } -#else - if ((hdr->ih_flags & IMAGE_F_ENCRYPTED_AES128) && - (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES256)) - { - return false; - } #endif #if !defined(MCUBOOT_DECOMPRESS_IMAGES) if (IS_COMPRESSED(hdr)) { return false; } -#else - if ((hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1) && - (hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) - { - return false; - } #endif return true; From a9d9b8831ce7e89394a4b7d2b862dd3d1239db3e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 124/238] Revert "[nrf fromtree] bootutil: loader: Remove encrypted/compressed images without support" This reverts commit 16e15ce40ec4a88f8adba1ffea6b1fc45ded9908. --- boot/bootutil/src/loader.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 5566f005e..f1f2777b3 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -877,9 +877,7 @@ split_image_check(struct image_header *app_hdr, * Check that this is a valid header. Valid means that the magic is * correct, and that the sizes/offsets are "sane". Sane means that * there is no overflow on the arithmetic, and that the result fits - * within the flash area we are in. Also check the flags in the image - * and class the image as invalid if flags for encryption/compression - * are present but these features are not enabled. + * within the flash area we are in. */ static bool boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fap, @@ -901,18 +899,6 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa return false; } -#if !defined(MCUBOOT_ENC_IMAGES) - if (IS_ENCRYPTED(hdr)) { - return false; - } -#endif - -#if !defined(MCUBOOT_DECOMPRESS_IMAGES) - if (IS_COMPRESSED(hdr)) { - return false; - } -#endif - return true; } From 89db1d54e5f3bb02fbda95231fa19d334c4692b0 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 125/238] Revert "[nrf fromtree] zephyr: Add Kconfig for decompression" This reverts commit 53722dac8b7eb5bf564abc338fa18f6df9a49679. --- boot/zephyr/Kconfig | 27 ------------------- .../include/mcuboot_config/mcuboot_config.h | 4 --- 2 files changed, 31 deletions(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 2dbfc3135..db2e0e8dc 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -721,33 +721,6 @@ config MCUBOOT_BOOT_BANNER config BOOT_BANNER_STRING default "Using Zephyr OS build" if MCUBOOT_BOOT_BANNER -config BOOT_DECOMPRESSION_SUPPORT - bool - help - Hidden symbol which should be selected if a system provided decompression support. - -if BOOT_DECOMPRESSION_SUPPORT - -menuconfig BOOT_DECOMPRESSION - bool "Decompression" - help - If enabled, will include support for compressed images being loaded to the secondary slot - which then get decompressed into the primary slot. This mode allows the secondary slot to - be smaller than primary slot which otherwise would not be allowed. - -if BOOT_DECOMPRESSION - -config BOOT_DECOMPRESSION_BUFFER_SIZE - int "Write buffer size" - range 16 16384 - default 4096 - help - The size of a secondary buffer used for writing decompressed data to the storage device. - -endif # BOOT_DECOMPRESSION - -endif # BOOT_DECOMPRESSION_SUPPORT - endmenu config MCUBOOT_DEVICE_SETTINGS diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 2f0cc243c..8f5d17bf5 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -127,10 +127,6 @@ #define MCUBOOT_ENCRYPT_X25519 #endif -#ifdef CONFIG_BOOT_DECOMPRESSION -#define MCUBOOT_DECOMPRESS_IMAGES -#endif - #ifdef CONFIG_BOOT_BOOTSTRAP #define MCUBOOT_BOOTSTRAP 1 #endif From ded8b9cb853ef8039b1c7d0f8513cd56c2ca406a Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 126/238] Revert "[nrf fromtree] bootutil: Add compressed image flags and TLV" This reverts commit da149891d1d1151a3eaa594da450690b2549b77d. --- boot/bootutil/include/bootutil/image.h | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 3e03f80dd..1f12d9512 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -71,13 +71,6 @@ struct flash_area; */ #define IMAGE_F_ROM_FIXED 0x00000100 -/* - * Flags that indicate if the image data is compressed - */ -#define IMAGE_F_COMPRESSED_LZMA1 0x00000200 -#define IMAGE_F_COMPRESSED_LZMA2 0x00000400 -#define IMAGE_F_COMPRESSED_ARM_THUMB_FLT 0x00000800 - /* * ECSDA224 is with NIST P-224 * ECSDA256 is with NIST P-256 @@ -108,18 +101,6 @@ struct flash_area; #define IMAGE_TLV_DEPENDENCY 0x40 /* Image depends on other image */ #define IMAGE_TLV_SEC_CNT 0x50 /* security counter */ #define IMAGE_TLV_BOOT_RECORD 0x60 /* measured boot record */ -/* The following flags relate to compressed images and are for the decompressed image data */ -#define IMAGE_TLV_DECOMP_SIZE 0x70 /* Decompressed image size excluding header/TLVs */ -#define IMAGE_TLV_DECOMP_SHA 0x71 /* - * Decompressed image shaX hash, this field must match - * the format and size of the raw slot (compressed) - * shaX hash - */ -#define IMAGE_TLV_DECOMP_SIGNATURE 0x72 /* - * Decompressed image signature, this field must match - * the format and size of the raw slot (compressed) - * signature - */ /* * vendor reserved TLVs at xxA0-xxFF, * where xx denotes the upper byte @@ -179,12 +160,6 @@ struct image_tlv { #define MUST_DECRYPT(fap, idx, hdr) \ (flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_ENCRYPTED(hdr)) -#define COMPRESSIONFLAGS (IMAGE_F_COMPRESSED_LZMA1 | IMAGE_F_COMPRESSED_LZMA2 \ - | IMAGE_F_COMPRESSED_ARM_THUMB_FLT) -#define IS_COMPRESSED(hdr) ((hdr)->ih_flags & COMPRESSIONFLAGS) -#define MUST_DECOMPRESS(fap, idx, hdr) \ - (flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_COMPRESSED(hdr)) - _Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE, "struct image_header not required size"); From b6c79e1cfeb39def7c1efd3c51b1c14f303ae5ff Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 127/238] Revert "[nrf fromtree] docs: release-notes: Add note on bootutil changes" This reverts commit 4e74426743a307b47b66cedd4271077856799118. --- docs/release-notes.d/bootutil-image-verification.md | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 docs/release-notes.d/bootutil-image-verification.md diff --git a/docs/release-notes.d/bootutil-image-verification.md b/docs/release-notes.d/bootutil-image-verification.md deleted file mode 100644 index a1cc58842..000000000 --- a/docs/release-notes.d/bootutil-image-verification.md +++ /dev/null @@ -1,4 +0,0 @@ -- Changed bootutil's order of events to verify the image header - before checking the image. -- Added the bootloader state object to the bootutil - boot_is_header_valid() function From 9e0a3d542a7827a5aff5d493eadb9d5c064d7126 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 128/238] Revert "[nrf fromtree] bootutil: loader: Verify image header before checking image" This reverts commit 4e81dcd2d07c6dcce1126f984fdcbfec17574ab6. --- boot/bootutil/src/loader.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index f1f2777b3..08fd0faad 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1059,16 +1059,13 @@ boot_validate_slot(struct boot_loader_state *state, int slot, } } #endif - if (!boot_is_header_valid(hdr, fap, state)) { - fih_rc = FIH_FAILURE; - } else { - BOOT_HOOK_CALL_FIH(boot_image_check_hook, FIH_BOOT_HOOK_REGULAR, - fih_rc, BOOT_CURR_IMG(state), slot); - if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR)) { - FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs); - } + BOOT_HOOK_CALL_FIH(boot_image_check_hook, FIH_BOOT_HOOK_REGULAR, + fih_rc, BOOT_CURR_IMG(state), slot); + if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR)) + { + FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs); } - if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { + if (!boot_is_header_valid(hdr, fap, state) || FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { if ((slot != BOOT_PRIMARY_SLOT) || ARE_SLOTS_EQUIVALENT()) { flash_area_erase(fap, 0, flash_area_get_size(fap)); /* Image is invalid, erase it to prevent further unnecessary From df974c827f91484e2da29e888e852cc56140e0c0 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 129/238] Revert "[nrf fromtree] bootutil: loader: Add state to boot_is_header_valid() function" This reverts commit 0c076898551d3053e8b7b115b12650b3f704f4ed. --- boot/bootutil/src/loader.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 08fd0faad..41697a010 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -880,13 +880,10 @@ split_image_check(struct image_header *app_hdr, * within the flash area we are in. */ static bool -boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fap, - struct boot_loader_state *state) +boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fap) { uint32_t size; - (void)state; - if (hdr->ih_magic != IMAGE_MAGIC) { return false; } @@ -1065,7 +1062,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, { FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs); } - if (!boot_is_header_valid(hdr, fap, state) || FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { + if (!boot_is_header_valid(hdr, fap) || FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { if ((slot != BOOT_PRIMARY_SLOT) || ARE_SLOTS_EQUIVALENT()) { flash_area_erase(fap, 0, flash_area_get_size(fap)); /* Image is invalid, erase it to prevent further unnecessary @@ -2779,7 +2776,7 @@ boot_get_slot_usage(struct boot_loader_state *state) for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) { hdr = boot_img_hdr(state, slot); - if (boot_is_header_valid(hdr, BOOT_IMG_AREA(state, slot), state)) { + if (boot_is_header_valid(hdr, BOOT_IMG_AREA(state, slot))) { state->slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = true; BOOT_LOG_IMAGE_INFO(slot, hdr); } else { From c4148067476a719d4feeb73d859877938d8e2d89 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 130/238] Revert "[nrf noup] boards: nrf54l15dk: Disable FPROTECT" This reverts commit f30dce197f34d4df77d8e66997dff0ce948c2b82. --- boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf index 8d8eb845f..43d8cebe3 100644 --- a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf +++ b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf @@ -7,7 +7,4 @@ CONFIG_BOOT_MAX_IMG_SECTORS=256 # Ensure that the SPI NOR driver is disabled by default CONFIG_SPI_NOR=n -# TODO: below are not yet supported and need fixing -CONFIG_FPROTECT=n - CONFIG_BOOT_WATCHDOG_FEED=n From 5998c07215a7f105fdd690870683135030acc7a3 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 131/238] Revert "[nrf fromtree] boot: zephyr: boards: Add nrf54l15dk configuration" This reverts commit 9ac6f766295fdf9d639782148449f2587bc72a34. --- boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf deleted file mode 100644 index 43d8cebe3..000000000 --- a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2024 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 -# -CONFIG_BOOT_MAX_IMG_SECTORS=256 - -# Ensure that the SPI NOR driver is disabled by default -CONFIG_SPI_NOR=n - -CONFIG_BOOT_WATCHDOG_FEED=n From 92ae47f03657aa7d14c00e98178916317e87bd97 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 132/238] Revert "[nrf noup] bootutil: loader: Fix netcore address checking" This reverts commit 5db198194c10e7a99bad2742e87e8c503b6d2c60. --- boot/bootutil/src/loader.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 41697a010..f81bafca7 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1323,7 +1323,7 @@ boot_validated_swap_type(struct boot_loader_state *state, #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS - if(!(reset_addr >= PM_CPUNET_APP_ADDRESS && reset_addr < PM_CPUNET_APP_END_ADDRESS)) + if(reset_addr < PM_CPUNET_B0N_ADDRESS) #endif { const struct flash_area *primary_fa; @@ -1396,8 +1396,7 @@ boot_validated_swap_type(struct boot_loader_state *state, * update and indicate to the caller of this function that no update is * available */ - if (upgrade_valid && reset_addr >= PM_CPUNET_APP_ADDRESS && - reset_addr < PM_CPUNET_APP_END_ADDRESS) { + if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr); From 8166a7c655544eb6a6efe1fd4e4ed69bc0bd63cb Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 133/238] Revert "[nrf noup] Remove secure boot debug Kconfig" This reverts commit e66169aa8daf93eee0ff3729ecc2c343c7fade51. --- boot/zephyr/prj_minimal.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/prj_minimal.conf b/boot/zephyr/prj_minimal.conf index 55d4c6167..1f90e708b 100644 --- a/boot/zephyr/prj_minimal.conf +++ b/boot/zephyr/prj_minimal.conf @@ -34,6 +34,7 @@ CONFIG_NCS_SAMPLES_DEFAULTS=n CONFIG_NO_RUNTIME_CHECKS=y CONFIG_NRF_RTC_TIMER=n CONFIG_PRINTK=n +CONFIG_SECURE_BOOT_DEBUG=n CONFIG_SERIAL=n CONFIG_SIZE_OPTIMIZATIONS=y CONFIG_SYS_CLOCK_EXISTS=n From efc3998574ab7ab08d108bb44bba71476494fe70 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 134/238] Revert "[nrf noup] boot/../loader: reboot after updating s0/s1" This reverts commit daf2946a0f07a14b57bd69d29ac4cdde6f810fb7. --- boot/bootutil/src/loader.c | 10 ---------- boot/zephyr/Kconfig | 1 - 2 files changed, 11 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index f81bafca7..151944f1b 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,10 +49,6 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" -#ifdef __ZEPHYR__ -#include -#endif - #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) #include #ifdef CONFIG_PCD_READ_NETCORE_APP_VERSION @@ -2510,12 +2506,6 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) rc = boot_perform_update(state, &bs); } assert(rc == 0); -#if defined(PM_S1_ADDRESS) && defined(CONFIG_REBOOT) - if (owner_nsib[BOOT_CURR_IMG(state)]) { - sys_reboot(SYS_REBOOT_COLD); - - } -#endif break; case BOOT_SWAP_TYPE_FAIL: diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index db2e0e8dc..5f44a109a 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -18,7 +18,6 @@ config MCUBOOT select MPU_ALLOW_FLASH_WRITE if ARM_MPU select USE_DT_CODE_PARTITION if HAS_FLASH_LOAD_OFFSET select MCUBOOT_BOOTUTIL_LIB - select REBOOT if SECURE_BOOT config BOOT_USE_MBEDTLS bool From 8cc9b03ebad8e91ef837b3d8b65ba5dbda01788b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 135/238] Revert "[nrf noup] boot/../loader: skip downgrade prevention for s1/s0" This reverts commit d9fe0115232e5aa06b03de40c6cc91809f224540. --- boot/bootutil/src/loader.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 151944f1b..9c14c03e6 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -70,9 +70,6 @@ int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); BOOT_LOG_MODULE_DECLARE(mcuboot); static struct boot_loader_state boot_data; -#ifdef PM_S1_ADDRESS -static bool owner_nsib[BOOT_IMAGE_NUMBER] = {false}; -#endif #if (BOOT_IMAGE_NUMBER > 1) #define IMAGES_ITER(x) for ((x) = 0; (x) < BOOT_IMAGE_NUMBER; ++(x)) @@ -1289,9 +1286,6 @@ boot_validated_swap_type(struct boot_loader_state *state, int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); bool upgrade_valid = false; -#if defined(PM_S1_ADDRESS) - owner_nsib[BOOT_CURR_IMG(state)] = false; -#endif #if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) const struct flash_area *secondary_fa = @@ -1348,7 +1342,6 @@ boot_validated_swap_type(struct boot_loader_state *state, && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { /* Set primary to be NSIB upgrade slot */ BOOT_IMG_AREA(state, 0) = nsib_fa; - owner_nsib[BOOT_CURR_IMG(state)] = true; } #else return BOOT_SWAP_TYPE_NONE; @@ -1359,10 +1352,6 @@ boot_validated_swap_type(struct boot_loader_state *state, /* The image in the secondary slot is not intended for any */ return BOOT_SWAP_TYPE_NONE; } - - if ((primary_fa->fa_off == PM_S0_ADDRESS) || (primary_fa->fa_off == PM_S1_ADDRESS)) { - owner_nsib[BOOT_CURR_IMG(state)] = true; - } } #endif /* PM_S1_ADDRESS */ sec_slot_mark_assigned(state); @@ -2302,13 +2291,6 @@ check_downgrade_prevention(struct boot_loader_state *state) uint32_t security_counter[2]; int rc; -#if defined(PM_S1_ADDRESS) - if (owner_nsib[BOOT_CURR_IMG(state)]) { - /* Downgrade prevention on S0/S1 image is managed by NSIB */ - return 0; - } -#endif - if (MCUBOOT_DOWNGRADE_PREVENTION_SECURITY_COUNTER) { /* If there was security no counter in slot 0, allow swap */ rc = bootutil_get_img_security_cnt(&(BOOT_IMG(state, 0).hdr), From ab42bfc632d098f184edb8898d0da9f1c22d2981 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 136/238] Revert "[nrf noup] boot: zephyr: Add NCS boot banner" This reverts commit d639f907407e7a36bd1d68fc042946e33d433e23. --- boot/zephyr/prj.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index e4f7d9030..23b5f3b93 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -37,6 +37,3 @@ CONFIG_CBPRINTF_NANO=y ### Use the minimal C library to reduce flash usage CONFIG_MINIMAL_LIBC=y CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 - -# NCS boot banner -CONFIG_NCS_APPLICATION_BOOT_BANNER_STRING="MCUboot" From c44b0978fb978d9d56857742ea705ad6d55c0dff Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 137/238] Revert "[nrf noup] zephyr/boards: fix nrf54l15pdk ext flash dts overlay" This reverts commit 4f84ba9bdf6c4a97457e6f74096b83e97ce9ce35. --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index 60ee6fe51..ea024fcec 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -14,8 +14,7 @@ /delete-node/ &storage_partition; -&cpuapp_rram { - reg = < 0x0 DT_SIZE_K(1524) >; +&rram0 { partitions { boot_partition: partition@0 { label = "mcuboot"; From c52da26f0442e419336ebbe259220a23ebeb3681 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 138/238] Revert "[nrf noup] Revert of zephyr: arm: Update reading the flash image reset vector" This reverts commit 0f317a215e16885d744b84ee6bee662846159844. --- boot/zephyr/flash_map_extended.c | 8 ++++++-- boot/zephyr/main.c | 20 +++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c index d0744afbd..4631da75b 100644 --- a/boot/zephyr/flash_map_extended.c +++ b/boot/zephyr/flash_map_extended.c @@ -141,8 +141,12 @@ int flash_area_sector_from_off(off_t off, struct flash_sector *sector) uint8_t flash_area_get_device_id(const struct flash_area *fa) { - (void)fa; - return FLASH_DEVICE_ID; +#if defined(CONFIG_ARM) + return fa->fa_id; +#else + (void)fa; + return FLASH_DEVICE_ID; +#endif } #define ERASED_VAL 0xff diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index e3347a2fa..b4cf43602 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -174,16 +174,26 @@ static void do_boot(struct boot_rsp *rsp) /* Get ram address for image */ vt = (struct arm_vector_table *)(rsp->br_hdr->ih_load_addr + rsp->br_hdr->ih_hdr_size); #else - uintptr_t flash_base; int rc; + const struct flash_area *fap; + static uint32_t dst[2]; /* Jump to flash image */ - rc = flash_device_base(rsp->br_flash_dev_id, &flash_base); + rc = flash_area_open(rsp->br_flash_dev_id, &fap); + assert(rc == 0); + + rc = flash_area_read(fap, rsp->br_hdr->ih_hdr_size, dst, sizeof(dst)); assert(rc == 0); +#ifndef CONFIG_ASSERT + /* Enter a lock up as asserts are disabled */ + if (rc != 0) { + while (1); + } +#endif + + flash_area_close(fap); - vt = (struct arm_vector_table *)(flash_base + - rsp->br_image_off + - rsp->br_hdr->ih_hdr_size); + vt = (struct arm_vector_table *)dst; #endif if (IS_ENABLED(CONFIG_SYSTEM_TIMER_HAS_DISABLE_SUPPORT)) { From 27de2af553eee3edf6830e18406d6f89e2a1d5a4 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 139/238] Revert "[nrf noup] boot/zephyr: fix fw_info search" This reverts commit f3ae1af0b0777b6bde918d9190bff22ef9ba705f. --- boot/zephyr/main.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index b4cf43602..b265481ae 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -206,14 +206,7 @@ static void do_boot(struct boot_rsp *rsp) #endif #if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - uintptr_t fw_start_addr; - - rc = flash_device_base(rsp->br_flash_dev_id, &fw_start_addr); - assert(rc == 0); - - fw_start_addr += rsp->br_image_off + rsp->br_hdr->ih_hdr_size; - - const struct fw_info *firmware_info = fw_info_find(fw_start_addr); + const struct fw_info *firmware_info = fw_info_find((uint32_t) vt); bool provided = fw_info_ext_api_provide(firmware_info, true); #ifdef PM_S0_ADDRESS From 2fb11265f886914f05d22b727e78c5cefff20a1e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 140/238] Revert "[nrf noup] boot: zephyr: Disable boot banner if NCS_BOOT_BANNER is used" This reverts commit f0a0c50c3d8a4a1ecc0564bc5c56b7454b01ad9d. --- boot/zephyr/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 5f44a109a..4b134b28f 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -705,7 +705,6 @@ config BOOT_DISABLE_CACHES config MCUBOOT_BOOT_BANNER bool "Use MCUboot boot banner" depends on BOOT_BANNER - depends on !NCS_BOOT_BANNER depends on "$(APP_VERSION_EXTENDED_STRING)" != "" default y help From 0a3f530a9d4c8facce1c43cac2a32864037e6ca7 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 141/238] Revert "[nrf noup] boards: thingy91x: enable serial recovery" This reverts commit 152f6411899b0d0f8b2c1597af476a2471191194. --- boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf | 10 ++-------- boot/zephyr/boards/thingy91x_nrf9151.conf | 9 --------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf index 37c7e95b1..72dfa7fca 100644 --- a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf @@ -32,7 +32,7 @@ CONFIG_USB_COMPOSITE_DEVICE=y CONFIG_USB_MASS_STORAGE=n CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x910A +CONFIG_USB_DEVICE_PID=0x520F CONFIG_BOOT_SERIAL_BOOT_MODE=y @@ -49,12 +49,6 @@ CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y CONFIG_FLASH_SIMULATOR_STATS=n CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y - -# Makes it possible to update the network core using the flash simulator -CONFIG_NRF53_RECOVERY_NETWORK_CORE=y - CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y -CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y -# Skip checks on the secondary image to make it possible to update MCUBoot on S1/S0 -CONFIG_MCUBOOT_VERIFY_IMG_ADDRESS=n +CONFIG_NRF53_RECOVERY_NETWORK_CORE=y diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf index 2efe1e170..33cd3301c 100644 --- a/boot/zephyr/boards/thingy91x_nrf9151.conf +++ b/boot/zephyr/boards/thingy91x_nrf9151.conf @@ -6,12 +6,3 @@ CONFIG_SPI_NOR=y CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 CONFIG_SPI_NOR_SFDP_DEVICETREE=y CONFIG_MULTITHREADING=y - -# Disable Zephyr console and use UART for MCUboot serial recovery instead -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_UART_CONSOLE=n -CONFIG_MCUBOOT_SERIAL=y - -CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y -CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y From 120c32cf5f65b77a6c67f291be0e47e20a45631a Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 142/238] Revert "[nrf noup] boot/zephyr/boards: nrf54l15pdk ext-flash update" This reverts commit 0656a67a1c74658a83e3aca7317b7642310998bd. --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf | 7 ------- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 1 - 2 files changed, 8 deletions(-) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf index 8fc12e074..841922dbd 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf @@ -6,10 +6,3 @@ CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 CONFIG_MAIN_STACK_SIZE=20480 CONFIG_BOOT_MAX_IMG_SECTORS=512 CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 -# Ensure that the qspi driver is disabled by default -CONFIG_NORDIC_QSPI_NOR=n - -# TODO: below are not yet supported and need fixing -CONFIG_FPROTECT=n - -CONFIG_BOOT_WATCHDOG_FEED=n diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index ea024fcec..76b648903 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -1,7 +1,6 @@ / { chosen { nordic,pm-ext-flash = &mx25r64; - zephyr,code-partition = &boot_partition; }; }; From a419c1358ce0c5b1727ed30b69d260eaf8995393 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 143/238] Revert "[nrf noup] boot/zephyr/boards: nrf54l15pdk ext-flash partition" This reverts commit 826a4071ed8458da61d1152530c3a0ba8fda58be. --- ...54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index 76b648903..2341ffd26 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -4,42 +4,7 @@ }; }; -/delete-node/ &boot_partition; -/delete-node/ &slot0_partition; -/delete-node/ &slot1_partition; - -/delete-node/ &slot0_ns_partition; -/delete-node/ &slot1_ns_partition; - -/delete-node/ &storage_partition; - -&rram0 { - partitions { - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x000000000 0x00014000>; - }; - slot0_partition: partition@14000 { - label = "image-0"; - reg = <0x000014000 0x0015A000>; - }; - storage_partition: partition@16E000 { - label = "storage"; - reg = < 0x16E000 0x9000 >; - }; - }; -}; &mx25r64 { status = "okay"; - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - slot1_partition: partition@0 { - label = "image-1"; - reg = <0x000000000 0x0015A000>; - }; - }; }; From 7e23c7cd59e8285f5a7ee067a59a90b4165160b2 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 144/238] Revert "[nrf noup] zephyr: Clean up non-secure RAM if enabled" This reverts commit b305c3d7d1514dea26d80c25ea0688a74011830b. --- boot/zephyr/nrf_cleanup.c | 66 ++++++++++++--------------------------- 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 051705ec9..2165159ea 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -5,8 +5,9 @@ */ #include -#include -#include +#if defined(NRF_UARTE0) || defined(NRF_UARTE1) + #include +#endif #if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) #include #endif @@ -23,11 +24,6 @@ #include #endif -#if defined(NRF_UARTE0) || defined(NRF_UARTE1) || defined(NRF_UARTE20) || \ - defined(NRF_UARTE30) -#define NRF_UARTE_CLEANUP -#endif - #define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) #define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ NRF_UARTE_SUBSCRIBE_CONF_OFFS) @@ -45,23 +41,6 @@ static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) } #endif -#if defined(NRF_UARTE_CLEANUP) -static NRF_UARTE_Type *nrf_uarte_to_clean[] = { -#if defined(NRF_UARTE0) - NRF_UARTE0, -#endif -#if defined(NRF_UARTE1) - NRF_UARTE1, -#endif -#if defined(NRF_UARTE20) - NRF_UARTE20, -#endif -#if defined(NRF_UARTE30) - NRF_UARTE30, -#endif -}; -#endif - static void nrf_cleanup_clock(void) { nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); @@ -78,31 +57,26 @@ void nrf_cleanup_peripheral(void) #if defined(NRF_RTC2) nrf_cleanup_rtc(NRF_RTC2); #endif - -#if defined(NRF_UARTE_CLEANUP) - for (int i = 0; i < sizeof(nrf_uarte_to_clean) / sizeof(nrf_uarte_to_clean[0]); ++i) { - NRF_UARTE_Type *current = nrf_uarte_to_clean[i]; - - nrfy_uarte_int_disable(current, 0xFFFFFFFF); - nrfy_uarte_int_uninit(current); - nrfy_uarte_task_trigger(current, NRF_UARTE_TASK_STOPRX); - - nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXSTARTED); - nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_ENDRX); - nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXTO); - nrfy_uarte_disable(current); - +#if defined(NRF_UARTE0) + nrf_uarte_disable(NRF_UARTE0); + nrf_uarte_int_disable(NRF_UARTE0, 0xFFFFFFFF); #if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)current + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, - NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)current + NRF_UARTE_PUBLISH_CONF_OFFS, 0, - NRF_UARTE_PUBLISH_CONF_SIZE); + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); +#endif +#endif +#if defined(NRF_UARTE1) + nrf_uarte_disable(NRF_UARTE1); + nrf_uarte_int_disable(NRF_UARTE1, 0xFFFFFFFF); +#if defined(NRF_DPPIC) + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); #endif - } #endif - #if defined(NRF_PPI) nrf_ppi_channels_disable_all(NRF_PPI); #endif From fd15c7dd65a03871b8962ce450d4909b5edf20c3 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 145/238] Revert "[nrf noup] loader: remove cleanup for direct xip mode" This reverts commit 3853d2664de779eaa3300a37a51628bf9c9f2513. --- boot/bootutil/src/loader.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 9c14c03e6..3b34b4b76 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1188,8 +1188,6 @@ boot_update_security_counter(uint8_t image_index, int slot, } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ -#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) - #if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ (defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP)) @@ -1271,6 +1269,7 @@ static inline void sec_slot_cleanup_if_unusable(void) #endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */ +#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) /** * Determines which swap operation to perform, if any. If it is determined * that a swap operation is required, the image in the secondary slot is checked From c8b99ac58e8ac318386c1f01361b95d5c502fffd Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 146/238] Revert "[nrf noup] boards: nrf54l15: Disable FPROTECT" This reverts commit ec59c38081d5b11fb00263a43981ba3756b28138. --- boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf index 03ad533f9..33e7e6124 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -7,7 +7,4 @@ CONFIG_BOOT_MAX_IMG_SECTORS=256 # Ensure that the qspi driver is disabled by default CONFIG_NORDIC_QSPI_NOR=n -# TODO: below are not yet supported and need fixing -CONFIG_FPROTECT=n - CONFIG_BOOT_WATCHDOG_FEED=n From 52152fdb5f6c158e7c038406877eb23c9d845543 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 147/238] Revert "[nrf noup] loader: introduced cleanup of unusable secondary slot" This reverts commit ee67c04d98ffc8b45140e76164499c9de31f77f0. --- boot/bootutil/src/loader.c | 90 -------------------------------------- 1 file changed, 90 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 3b34b4b76..a2c6ee5bd 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1188,87 +1188,6 @@ boot_update_security_counter(uint8_t image_index, int slot, } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ -#if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ -(defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP)) - -#define SEC_SLOT_VIRGIN 0 -#define SEC_SLOT_TOUCHED 1 -#define SEC_SLOT_ASSIGNED 2 - -#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -/* This configuration is peculiar - the one physical secondary slot is - * mocking two logical secondary - */ -#define SEC_SLOT_PHYSICAL_CNT 1 -#else -#define SEC_SLOT_PHYSICAL_CNT MCUBOOT_IMAGE_NUMBER -#endif - -static uint8_t sec_slot_assignmnet[SEC_SLOT_PHYSICAL_CNT] = {0}; - -static inline void sec_slot_touch(struct boot_loader_state *state) -{ - uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); - - if (SEC_SLOT_VIRGIN == sec_slot_assignmnet[idx]) { - sec_slot_assignmnet[idx] = SEC_SLOT_TOUCHED; - } -} - -static inline void sec_slot_mark_assigned(struct boot_loader_state *state) -{ - uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); - - sec_slot_assignmnet[idx] = SEC_SLOT_ASSIGNED; -} - -/** - * Cleanu up all secondary slot which couldn't be assigned to any primary slot. - * - * This function erases content of each secondary slot which contains valid - * header but couldn't be assigned to any of supported primary images. - * - * This function is supposed to be called after boot_validated_swap_type() - * iterates over all the images in context_boot_go(). - */ -static void sec_slot_cleanup_if_unusable(void) -{ - uint8_t idx; - - for (idx = 0; idx < SEC_SLOT_PHYSICAL_CNT; idx++) { - if (SEC_SLOT_TOUCHED == sec_slot_assignmnet[idx]) { - const struct flash_area *secondary_fa; - int rc; - - rc = flash_area_open(flash_area_id_from_multi_image_slot(idx, BOOT_SECONDARY_SLOT), - &secondary_fa); - if (!rc) { - rc = flash_area_erase(secondary_fa, 0, secondary_fa->fa_size); - if (!rc) { - BOOT_LOG_ERR("Cleaned-up secondary slot of %d. image.", idx); - } - } - - if (rc) { - BOOT_LOG_ERR("Can not cleanup secondary slot of %d. image.", idx); - } - } - } -} -#else -static inline void sec_slot_touch(struct boot_loader_state *state) -{ -} -static inline void sec_slot_mark_assigned(struct boot_loader_state *state) -{ -} -static inline void sec_slot_cleanup_if_unusable(void) -{ -} -#endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ - defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */ - #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) /** * Determines which swap operation to perform, if any. If it is determined @@ -1307,9 +1226,6 @@ boot_validated_swap_type(struct boot_loader_state *state, if (rc != 0) { return BOOT_SWAP_TYPE_FAIL; } - - sec_slot_touch(state); - #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS if(reset_addr < PM_CPUNET_B0N_ADDRESS) @@ -1344,7 +1260,6 @@ boot_validated_swap_type(struct boot_loader_state *state, } #else return BOOT_SWAP_TYPE_NONE; - #endif } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { @@ -1353,9 +1268,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } } #endif /* PM_S1_ADDRESS */ - sec_slot_mark_assigned(state); } - #endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); @@ -2416,9 +2329,6 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } } - /* cleanup secondary slots which were recognized unusable*/ - sec_slot_cleanup_if_unusable(); - #if (BOOT_IMAGE_NUMBER > 1) if (has_upgrade) { /* Iterate over all the images and verify whether the image dependencies From 414b7f9770c36f681241d5f956c70213115a766e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 148/238] Revert "[nrf noup] sysflash: Add support for three images" This reverts commit d2d11bf027a180f68447450a7b8615bc35ca016c. --- boot/zephyr/include/sysflash/pm_sysflash.h | 82 ++++++++++------------ 1 file changed, 37 insertions(+), 45 deletions(-) diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h index db60ddd03..377291e8b 100644 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -11,19 +11,37 @@ #include #include -#include #ifndef CONFIG_SINGLE_APPLICATION_SLOT -#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) +#if (MCUBOOT_IMAGE_NUMBER == 1) + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID + +#elif (MCUBOOT_IMAGE_NUMBER == 2) + /* If B0 is present then two bootloaders are present, and we must use * a single secondary slot for both primary slots. */ +#if defined(PM_B0_ADDRESS) extern uint32_t _image_1_primary_slot_id[]; -#endif /* (MCUBOOT_IMAGE_NUMBER == 2 && defined(PM_B0_ADDRESS) */ +#endif +#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) -#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) +#elif defined(PM_B0_ADDRESS) #define FLASH_AREA_IMAGE_PRIMARY(x) \ ((x == 0) ? \ @@ -38,52 +56,26 @@ extern uint32_t _image_1_primary_slot_id[]; (x == 1) ? \ PM_MCUBOOT_SECONDARY_ID: \ 255 ) - -#else /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) - */ - -/* Each pair of slots is separated by , and there is no terminating character */ -#define FLASH_AREA_IMAGE_0_SLOTS PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID -#define FLASH_AREA_IMAGE_1_SLOTS PM_MCUBOOT_PRIMARY_1_ID, PM_MCUBOOT_SECONDARY_1_ID -#define FLASH_AREA_IMAGE_2_SLOTS PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID - -#if (MCUBOOT_IMAGE_NUMBER == 1) -#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS -#elif (MCUBOOT_IMAGE_NUMBER == 2) -#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ - FLASH_AREA_IMAGE_1_SLOTS -#elif (MCUBOOT_IMAGE_NUMBER == 3) -#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ - FLASH_AREA_IMAGE_1_SLOTS, \ - FLASH_AREA_IMAGE_2_SLOTS #else -#error Unsupported number of images -#endif -static inline uint32_t __flash_area_ids_for_slot(int img, int slot) -{ - static const int all_slots[] = { - ALL_AVAILABLE_SLOTS - }; - return all_slots[img * 2 + slot]; -}; +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) -#undef FLASH_AREA_IMAGE_0_SLOTS -#undef FLASH_AREA_IMAGE_1_SLOTS -#undef FLASH_AREA_IMAGE_2_SLOTS -#undef ALL_AVAILABLE_SLOTS +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) -#define FLASH_AREA_IMAGE_PRIMARY(x) __flash_area_ids_for_slot(x, 0) -#define FLASH_AREA_IMAGE_SECONDARY(x) __flash_area_ids_for_slot(x, 1) +#endif /* PM_B0_ADDRESS */ -#if !defined(CONFIG_BOOT_SWAP_USING_MOVE) -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID #endif - -#endif /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) - */ +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID #else /* CONFIG_SINGLE_APPLICATION_SLOT */ From e6483196d9f130af6d4d9b9dde317573f4d5ef1f Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 149/238] Revert "[nrf noup] sysflash: Move partition manager definitions to pm_sysflash.h" This reverts commit 6cecb1c14aa4e934e12fd00fdc68e6ee2fdbef78. --- boot/zephyr/include/sysflash/pm_sysflash.h | 92 ---------------------- boot/zephyr/include/sysflash/sysflash.h | 90 +++++++++++++++++++-- 2 files changed, 85 insertions(+), 97 deletions(-) delete mode 100644 boot/zephyr/include/sysflash/pm_sysflash.h diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h deleted file mode 100644 index 377291e8b..000000000 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#ifndef __PM_SYSFLASH_H__ -#define __PM_SYSFLASH_H__ -/* Blocking the __SYSFLASH_H__ */ -#define __SYSFLASH_H__ - -#include -#include - -#ifndef CONFIG_SINGLE_APPLICATION_SLOT - -#if (MCUBOOT_IMAGE_NUMBER == 1) - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID - -#elif (MCUBOOT_IMAGE_NUMBER == 2) - -/* If B0 is present then two bootloaders are present, and we must use - * a single secondary slot for both primary slots. - */ -#if defined(PM_B0_ADDRESS) -extern uint32_t _image_1_primary_slot_id[]; -#endif -#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) -#elif defined(PM_B0_ADDRESS) - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - (uint32_t)_image_1_primary_slot_id : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - 255 ) -#else - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) - -#endif /* PM_B0_ADDRESS */ - -#endif -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID - -#else /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID -/* NOTE: Scratch parition is not used by single image DFU but some of - * functions in common files reference it, so the definitions has been - * provided to allow compilation of common units. - */ -#define FLASH_AREA_IMAGE_SCRATCH 0 - -#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#endif /* __PM_SYSFLASH_H__ */ diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index f231c3d02..8b47a32b5 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -4,15 +4,93 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if USE_PARTITION_MANAGER -/* Blocking the rest of the file */ +#ifndef __SYSFLASH_H__ #define __SYSFLASH_H__ -#include + +#if USE_PARTITION_MANAGER +#include +#include + +#ifndef CONFIG_SINGLE_APPLICATION_SLOT + +#if (MCUBOOT_IMAGE_NUMBER == 1) + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID + +#elif (MCUBOOT_IMAGE_NUMBER == 2) + +/* If B0 is present then two bootloaders are present, and we must use + * a single secondary slot for both primary slots. + */ +#if defined(PM_B0_ADDRESS) +extern uint32_t _image_1_primary_slot_id[]; #endif +#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) +#elif defined(PM_B0_ADDRESS) + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + (uint32_t)_image_1_primary_slot_id : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + 255 ) +#else + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) + +#endif /* PM_B0_ADDRESS */ -#ifndef __SYSFLASH_H__ -#define __SYSFLASH_H__ +#endif +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID + +#else /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID +/* NOTE: Scratch parition is not used by single image DFU but some of + * functions in common files reference it, so the definitions has been + * provided to allow compilation of common units. + */ +#define FLASH_AREA_IMAGE_SCRATCH 0 + +#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ +#else + +#include #include #include #include @@ -71,4 +149,6 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ +#endif /* USE_PARTITION_MANAGER */ + #endif /* __SYSFLASH_H__ */ From 5161b828c08a166ee6ba67230ff839820c681ed1 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 150/238] Revert "[nrf noup] boot: Add support for NSIB and multi-image" This reverts commit ce42cace17415ee62d1743e77bdbb3fbe6edc2f0. --- boot/bootutil/src/loader.c | 44 ++++++------------------- boot/zephyr/include/sysflash/sysflash.h | 19 ++--------- 2 files changed, 12 insertions(+), 51 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index a2c6ee5bd..200a3e8e8 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1108,11 +1108,6 @@ boot_validate_slot(struct boot_loader_state *state, int slot, if (BOOT_CURR_IMG(state) == 1) { min_addr = PM_CPUNET_APP_ADDRESS; max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; -#ifdef PM_S1_ADDRESS - } else if (BOOT_CURR_IMG(state) == 0) { - min_addr = PM_S0_ADDRESS; - max_addr = pri_fa->fa_off + pri_fa->fa_size; -#endif } else #endif { @@ -1233,37 +1228,18 @@ boot_validated_swap_type(struct boot_loader_state *state, { const struct flash_area *primary_fa; rc = flash_area_open(flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT), - &primary_fa); + BOOT_CURR_IMG(state), + BOOT_PRIMARY_SLOT), + &primary_fa); + if (rc != 0) { return BOOT_SWAP_TYPE_FAIL; } - - /* Check start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off) { -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) - const struct flash_area *nsib_fa; - - /* NSIB upgrade slot */ - rc = flash_area_open((uint32_t)_image_1_primary_slot_id, - &nsib_fa); - - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } - - /* Image is placed before Primary and within the NSIB slot */ - if (reset_addr > nsib_fa->fa_off - && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { - /* Set primary to be NSIB upgrade slot */ - BOOT_IMG_AREA(state, 0) = nsib_fa; - } -#else - return BOOT_SWAP_TYPE_NONE; -#endif - - } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for any */ + /* Get start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off || + reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for this image + */ return BOOT_SWAP_TYPE_NONE; } } @@ -1527,7 +1503,7 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) BOOT_LOG_INF("Image %d upgrade secondary slot -> primary slot", image_index); BOOT_LOG_INF("Erasing the primary slot"); - rc = flash_area_open(flash_area_get_id(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)), + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), &fap_primary_slot); assert (rc == 0); diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 8b47a32b5..b98e48bce 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -23,24 +23,9 @@ /* If B0 is present then two bootloaders are present, and we must use * a single secondary slot for both primary slots. */ -#if defined(PM_B0_ADDRESS) -extern uint32_t _image_1_primary_slot_id[]; -#endif -#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) +#ifdef PM_B0_ADDRESS -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) -#elif defined(PM_B0_ADDRESS) +extern uint32_t _image_1_primary_slot_id[]; #define FLASH_AREA_IMAGE_PRIMARY(x) \ ((x == 0) ? \ From dab516bff8eac21fd286ea3ccd0437c17f04b38b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 151/238] Revert "[nrf noup] loader: Fix missing PCD define check" This reverts commit f15d38432b3e86f4a9a43e95a686041523ca5419. --- boot/bootutil/src/loader.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 200a3e8e8..0454bbd3d 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1264,7 +1264,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) \ - && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) && defined(CONFIG_PCD_APP) + && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) /* If the update is valid, and it targets the network core: perform the * update and indicate to the caller of this function that no update is * available @@ -1292,8 +1292,7 @@ boot_validated_swap_type(struct boot_loader_state *state, swap_type = BOOT_SWAP_TYPE_NONE; } } -#endif /* CONFIG_SOC_NRF5340_CPUAPP && PM_CPUNET_B0N_ADDRESS && - !CONFIG_NRF53_MULTI_IMAGE_UPDATE && CONFIG_PCD_APP */ +#endif /* CONFIG_SOC_NRF5340_CPUAPP */ } return swap_type; From adc5521d7779cbc44e3131c6e934f9282df22b39 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 152/238] Revert "[nrf noup] loader: work-around for multi-image builds" This reverts commit 843ee8e437ba50d99cc5490a9c46024f8bddf242. --- boot/bootutil/src/loader.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 0454bbd3d..749d93570 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -402,7 +402,7 @@ boot_verify_dependencies(struct boot_loader_state *state) if (rc == 0) { /* All dependencies've been satisfied, continue with next image. */ BOOT_CURR_IMG(state)++; - } else if (rc == BOOT_EBADIMAGE) { + } else { /* Cannot upgrade due to non-met dependencies, so disable all * image upgrades. */ @@ -411,10 +411,7 @@ boot_verify_dependencies(struct boot_loader_state *state) BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE; } break; - } else { - /* Other error happened, images are inconsistent */ - return rc; - } + } } return rc; } @@ -1758,6 +1755,7 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) } #endif + /** * Performs a clean (not aborted) image update. * From 7ca5e891e0bdae1958863e1152fc82b6598c7f9b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:40 +0200 Subject: [PATCH 153/238] Revert "[nrf noup] boot/zephyr/boards: nRF54l15pdk ext flash cfg" This reverts commit 0fcc1f8f5f6d94d49de722c745fd57b9a76c32e8. --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf | 8 -------- .../nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 10 ---------- 2 files changed, 18 deletions(-) delete mode 100644 boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf delete mode 100644 boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf deleted file mode 100644 index 841922dbd..000000000 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG_MULTITHREADING=y -CONFIG_SPI=y -CONFIG_SPI_NOR=y -CONFIG_FLASH=y -CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 -CONFIG_MAIN_STACK_SIZE=20480 -CONFIG_BOOT_MAX_IMG_SECTORS=512 -CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay deleted file mode 100644 index 2341ffd26..000000000 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ /dev/null @@ -1,10 +0,0 @@ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; - - -&mx25r64 { - status = "okay"; -}; From 5d709c99919311be9cc830cb5481c0efee3fb86d Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 154/238] Revert "[nrf noup] boards: thingy53: disable GPIO ISR support" This reverts commit 737742172f400320182e620b8ec2da8cf7d491b8. --- boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf index e10656678..7d3bc0bec 100644 --- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf @@ -21,7 +21,6 @@ CONFIG_UART_LINE_CTRL=y # MCUBoot serial CONFIG_GPIO=y -CONFIG_GPIO_NRFX_INTERRUPT=n CONFIG_MCUBOOT_SERIAL=y CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y CONFIG_BOOT_SERIAL_CDC_ACM=y From 298973d92208d4ac25e4023ad399ad30962f8bad Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 155/238] =?UTF-8?q?Revert=20"[nrf=20noup]=C2=A0loader:=20A?= =?UTF-8?q?dd=20firmware=20version=20check=20downgrade=20prevention"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit b0457784952ec666d86e9f9c9ae83341dc1c0bf4. --- boot/bootutil/src/loader.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 749d93570..bafcfefc7 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -51,10 +51,6 @@ #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) #include -#ifdef CONFIG_PCD_READ_NETCORE_APP_VERSION -#include -int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); -#endif #endif #ifdef MCUBOOT_ENC_IMAGES @@ -1020,21 +1016,9 @@ boot_validate_slot(struct boot_loader_state *state, int slot, #if defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION) if (slot != BOOT_PRIMARY_SLOT) { /* Check if version of secondary slot is sufficient */ - -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) \ - && defined(CONFIG_PCD_APP) && defined(CONFIG_PCD_READ_NETCORE_APP_VERSION) - if (BOOT_CURR_IMG(state) == 1) { - rc = pcd_version_cmp_net(fap, boot_img_hdr(state, BOOT_SECONDARY_SLOT)); - } else { - rc = boot_version_cmp( - &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, - &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); - } -#else - rc = boot_version_cmp( - &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, - &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); -#endif + rc = boot_version_cmp( + &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, + &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) { BOOT_LOG_ERR("insufficient version in secondary slot"); flash_area_erase(fap, 0, flash_area_get_size(fap)); From ad45a1c5927693ae0cc8095bede8ef152e63a5b4 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 156/238] Revert "[nrf noup] zephyr: Boot even if EXT_ABI is not provided" This reverts commit 62b5dc1c03be60da3456775b11f08a23c6cbb4bb. --- boot/zephyr/main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index b265481ae..13e3b69c1 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -206,16 +206,13 @@ static void do_boot(struct boot_rsp *rsp) #endif #if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - const struct fw_info *firmware_info = fw_info_find((uint32_t) vt); - bool provided = fw_info_ext_api_provide(firmware_info, true); + bool provided = fw_info_ext_api_provide(fw_info_find((uint32_t)vt), true); #ifdef PM_S0_ADDRESS /* Only fail if the immutable bootloader is present. */ if (!provided) { - if (firmware_info == NULL) { - BOOT_LOG_WRN("Unable to find firmware info structure in %p", vt); - } - BOOT_LOG_ERR("Failed to provide EXT_APIs to %p", vt); + BOOT_LOG_ERR("Failed to provide EXT_APIs\n"); + return; } #endif #endif From 9c3aaa28b93d7cf56ee9fc0c2ce1b0beb49ee1bd Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 157/238] Revert "[nrf noup] zephyr: Add RAM flash configuration to cache for sysbuild" This reverts commit 33effae0cce49991dfbd3ec4526f65ac305ae8dd. --- boot/zephyr/CMakeLists.txt | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index f26b090a6..3b107ddd2 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -532,14 +532,3 @@ zephyr_library_sources( ${BOOT_DIR}/zephyr/nrf_cleanup.c ) endif() - -if(SYSBUILD AND CONFIG_PCD_APP) - # Sysbuild requires details of the RAM flash device are stored to the cache of MCUboot so - # that they can be read when running partition manager - dt_nodelabel(ram_flash_dev NODELABEL flash_sim0) - dt_reg_addr(ram_flash_addr PATH ${ram_flash_dev}) - dt_reg_size(ram_flash_size PATH ${ram_flash_dev}) - - set(RAM_FLASH_ADDR "${ram_flash_addr}" CACHE STRING "" FORCE) - set(RAM_FLASH_SIZE "${ram_flash_size}" CACHE STRING "" FORCE) -endif() From aef3d0a7fa31c9217fc1fc47d7ee525ef8c87aba Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 158/238] Revert "[nrf noup] loader: Do not check reset vector for XIP image" This reverts commit 5fe56c9acdb8ff31788aa89f42673d43e0197639. --- boot/bootutil/src/loader.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index bafcfefc7..06e16d686 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1057,16 +1057,6 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * overwriting an application written to the incorrect slot. * This feature is only supported by ARM platforms. */ -#if MCUBOOT_IMAGE_NUMBER >= 3 - /* Currently the MCUboot can be configured for up to 3 image, where image number 2 is - * designated for XIP, where it is the second part of image stored in slots of image - * 0. This part of image is not bootable, as the XIP setup is done by the app in - * image 0 slot, and it does not carry the reset vector. - */ - if (area_id == FLASH_AREA_IMAGE_SECONDARY(2)) { - goto out; - } -#endif if (area_id == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) { const struct flash_area *pri_fa = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); struct image_header *secondary_hdr = boot_img_hdr(state, slot); From 1d60ea25dd702a2500e6646058bd74c37dcfc4cf Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 159/238] Revert "[nrf noup] zephyr: Fix path variables" This reverts commit 6f1ba9169c74458cb5bc9985277e228479cc6c63. --- boot/zephyr/CMakeLists.txt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 3b107ddd2..177f1d98a 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -27,20 +27,21 @@ assert_exists(FIAT_DIR) # Path to mbed-tls' asn1 parser library. set(MBEDTLS_ASN1_DIR "${MCUBOOT_DIR}/ext/mbedtls-asn1") assert_exists(MBEDTLS_ASN1_DIR) -set(MCUBOOT_NRF_EXT_DIR "${MCUBOOT_DIR}/ext/nrf") +set(NRF_DIR "${MCUBOOT_DIR}/ext/nrf") if(CONFIG_BOOT_USE_NRF_CC310_BL) - if(NOT EXISTS ${ZEPHYR_NRFXLIB_MODULE_DIR}) - message(FATAL_ERROR " +set(NRFXLIB_DIR ${ZEPHYR_BASE}/../nrfxlib) +if(NOT EXISTS ${NRFXLIB_DIR}) + message(FATAL_ERROR " ------------------------------------------------------------------------ - No such file or directory: ${ZEPHYR_NRFXLIB_MODULE_DIR} + No such file or directory: ${NRFXLIB_DIR} The current configuration enables nRF CC310 crypto accelerator hardware with the `CONFIG_BOOT_USE_NRF_CC310_BL` option. Please follow `ext/nrf/README.md` guide to fix your setup or use tinycrypt instead of the HW accelerator. To use the tinycrypt set `CONFIG_BOOT_ECDSA_TINYCRYPT` to y. ------------------------------------------------------------------------") - endif() +endif() endif() zephyr_library_include_directories( @@ -168,8 +169,8 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) ${TINYCRYPT_DIR}/source/utils.c ) elseif(CONFIG_BOOT_USE_NRF_CC310_BL) - zephyr_library_sources(${MCUBOOT_NRF_EXT_DIR}/cc310_glue.c) - zephyr_library_include_directories(${MCUBOOT_NRF_EXT_DIR}) + zephyr_library_sources(${NRF_DIR}/cc310_glue.c) + zephyr_library_include_directories(${NRF_DIR}) zephyr_link_libraries(nrfxlib_crypto) endif() From 1e6838c25dc6b68c994cfdee23c4b1ff28200fcf Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 160/238] Revert "[nrf noup] loader: Fix reading reset addr to support ext flash" This reverts commit a3d07726648f14d933a2039c20e007addb2a6381. --- boot/bootutil/src/loader.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 06e16d686..568c28e45 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1174,9 +1174,10 @@ boot_validated_swap_type(struct boot_loader_state *state, #if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) const struct flash_area *secondary_fa = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; + uint32_t vtable_addr = 0; + uint32_t *vtable = 0; uint32_t reset_addr = 0; - int rc = 0; /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other * B1 slot S0 or S1) share the same secondary slot, we need to check * whether the update candidate in the secondary slot is intended for @@ -1186,19 +1187,16 @@ boot_validated_swap_type(struct boot_loader_state *state, */ if (hdr->ih_magic == IMAGE_MAGIC) { - rc = flash_area_read(secondary_fa, hdr->ih_hdr_size + - sizeof(uint32_t), &reset_addr, - sizeof(reset_addr)); - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } + vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + vtable = (uint32_t *)(vtable_addr); + reset_addr = vtable[1]; #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS if(reset_addr < PM_CPUNET_B0N_ADDRESS) #endif { const struct flash_area *primary_fa; - rc = flash_area_open(flash_area_id_from_multi_image_slot( + int rc = flash_area_open(flash_area_id_from_multi_image_slot( BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT), &primary_fa); @@ -1234,19 +1232,16 @@ boot_validated_swap_type(struct boot_loader_state *state, upgrade_valid = true; } -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) \ - && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) /* If the update is valid, and it targets the network core: perform the * update and indicate to the caller of this function that no update is * available */ if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { - struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; - uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr); uint32_t fw_size = hdr->ih_img_size; + BOOT_LOG_INF("Starting network core update"); - rc = pcd_network_core_update(net_core_fw_addr, fw_size); + int rc = pcd_network_core_update(vtable, fw_size); if (rc != 0) { swap_type = BOOT_SWAP_TYPE_FAIL; From 984cacc1eb18e22c561726b8e3b93c6918777516 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 161/238] Revert "[nrf noup] zephyr: Clean up non-secure RAM if enabled" This reverts commit cc6103b060affb7ff3b3954aea828efe8111119a. --- boot/zephyr/CMakeLists.txt | 2 +- boot/zephyr/include/nrf_cleanup.h | 5 ----- boot/zephyr/main.c | 5 +---- boot/zephyr/nrf_cleanup.c | 13 ------------- 4 files changed, 2 insertions(+), 23 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 177f1d98a..d8766f60c 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -528,7 +528,7 @@ if(SYSBUILD) set(mcuboot_image_upgrade_footer_size ${required_upgrade_size} CACHE INTERNAL "Estimated MCUboot update image trailer size" FORCE) endif() -if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL OR CONFIG_MCUBOOT_CLEANUP_NONSECURE_RAM) +if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL) zephyr_library_sources( ${BOOT_DIR}/zephyr/nrf_cleanup.c ) diff --git a/boot/zephyr/include/nrf_cleanup.h b/boot/zephyr/include/nrf_cleanup.h index 9e87e13f5..6b04cedfe 100644 --- a/boot/zephyr/include/nrf_cleanup.h +++ b/boot/zephyr/include/nrf_cleanup.h @@ -16,9 +16,4 @@ */ void nrf_cleanup_peripheral(void); -/** - * Perform cleanup of non-secure RAM that may have been used by MCUBoot. - */ -void nrf_cleanup_ns_ram(void); - #endif diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 13e3b69c1..cd4e6cb46 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -142,7 +142,7 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); #include #endif -#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL || CONFIG_MCUBOOT_NRF_CLEANUP_NONSECURE_RAM +#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL #include #endif @@ -219,9 +219,6 @@ static void do_boot(struct boot_rsp *rsp) #if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL nrf_cleanup_peripheral(); #endif -#if CONFIG_MCUBOOT_NRF_CLEANUP_NONSECURE_RAM && defined(PM_SRAM_NONSECURE_NAME) - nrf_cleanup_ns_ram(); -#endif #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 2165159ea..5bab26b24 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -20,10 +20,6 @@ #include -#if USE_PARTITION_MANAGER -#include -#endif - #define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) #define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ NRF_UARTE_SUBSCRIBE_CONF_OFFS) @@ -85,12 +81,3 @@ void nrf_cleanup_peripheral(void) #endif nrf_cleanup_clock(); } - -#if USE_PARTITION_MANAGER \ - && defined(CONFIG_ARM_TRUSTZONE_M) \ - && defined(PM_SRAM_NONSECURE_NAME) -void nrf_cleanup_ns_ram(void) -{ - memset((void *) PM_SRAM_NONSECURE_ADDRESS, 0, PM_SRAM_NONSECURE_SIZE); -} -#endif From a02c59d910a827d34cb3edde609e2cf7963c5a1b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 162/238] Revert "[nrf noup] zephyr: clean peripherals state before boot" This reverts commit c033da00051c89b9534bbf764867f9479b0cf352. --- boot/zephyr/CMakeLists.txt | 6 --- boot/zephyr/include/nrf_cleanup.h | 19 ------- boot/zephyr/main.c | 8 +-- boot/zephyr/nrf_cleanup.c | 83 ------------------------------- 4 files changed, 1 insertion(+), 115 deletions(-) delete mode 100644 boot/zephyr/include/nrf_cleanup.h delete mode 100644 boot/zephyr/nrf_cleanup.c diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index d8766f60c..ddf9394d3 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -527,9 +527,3 @@ if(SYSBUILD) set(mcuboot_image_footer_size ${required_size} CACHE INTERNAL "Estimated MCUboot image trailer size" FORCE) set(mcuboot_image_upgrade_footer_size ${required_upgrade_size} CACHE INTERNAL "Estimated MCUboot update image trailer size" FORCE) endif() - -if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL) -zephyr_library_sources( - ${BOOT_DIR}/zephyr/nrf_cleanup.c -) -endif() diff --git a/boot/zephyr/include/nrf_cleanup.h b/boot/zephyr/include/nrf_cleanup.h deleted file mode 100644 index 6b04cedfe..000000000 --- a/boot/zephyr/include/nrf_cleanup.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#ifndef H_NRF_CLEANUP_ -#define H_NRF_CLEANUP_ - -/** - * Perform cleanup on some peripheral resources used by MCUBoot prior chainload - * the application. - * - * This function disables all RTC instances and UARTE instances. - * It Disables their interrupts signals as well. - */ -void nrf_cleanup_peripheral(void); - -#endif diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index cd4e6cb46..fe37ff01d 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -142,10 +142,6 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); #include #endif -#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL -#include -#endif - BOOT_LOG_MODULE_REGISTER(mcuboot); void os_heap_init(void); @@ -216,9 +212,7 @@ static void do_boot(struct boot_rsp *rsp) } #endif #endif -#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL - nrf_cleanup_peripheral(); -#endif + #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c deleted file mode 100644 index 5bab26b24..000000000 --- a/boot/zephyr/nrf_cleanup.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#include -#if defined(NRF_UARTE0) || defined(NRF_UARTE1) - #include -#endif -#if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) - #include -#endif -#if defined(NRF_PPI) - #include -#endif -#if defined(NRF_DPPIC) - #include -#endif - -#include - -#define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) -#define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ - NRF_UARTE_SUBSCRIBE_CONF_OFFS) - -#define NRF_UARTE_PUBLISH_CONF_OFFS offsetof(NRF_UARTE_Type, PUBLISH_CTS) -#define NRF_UARTE_PUBLISH_CONF_SIZE (offsetof(NRF_UARTE_Type, SHORTS) -\ - NRF_UARTE_PUBLISH_CONF_OFFS) - -#if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) -static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) -{ - nrf_rtc_task_trigger(rtc_reg, NRF_RTC_TASK_STOP); - nrf_rtc_event_disable(rtc_reg, 0xFFFFFFFF); - nrf_rtc_int_disable(rtc_reg, 0xFFFFFFFF); -} -#endif - -static void nrf_cleanup_clock(void) -{ - nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); -} - -void nrf_cleanup_peripheral(void) -{ -#if defined(NRF_RTC0) - nrf_cleanup_rtc(NRF_RTC0); -#endif -#if defined(NRF_RTC1) - nrf_cleanup_rtc(NRF_RTC1); -#endif -#if defined(NRF_RTC2) - nrf_cleanup_rtc(NRF_RTC2); -#endif -#if defined(NRF_UARTE0) - nrf_uarte_disable(NRF_UARTE0); - nrf_uarte_int_disable(NRF_UARTE0, 0xFFFFFFFF); -#if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); -#endif -#endif -#if defined(NRF_UARTE1) - nrf_uarte_disable(NRF_UARTE1); - nrf_uarte_int_disable(NRF_UARTE1, 0xFFFFFFFF); -#if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); -#endif -#endif -#if defined(NRF_PPI) - nrf_ppi_channels_disable_all(NRF_PPI); -#endif -#if defined(NRF_DPPIC) - nrf_dppi_channels_disable_all(NRF_DPPIC); -#endif - nrf_cleanup_clock(); -} From a8b99342f5d83d3aae5038ecda7c2d570990589b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 163/238] Revert "[nrf noup] boot: nrf53-specific customizations" This reverts commit cab8ef90e391f3b230ccc3657c7cac2bf9d52413. --- boot/bootutil/src/loader.c | 96 +++++-------------- .../boards/thingy53_nrf5340_cpuapp.conf | 73 -------------- boot/zephyr/include/sysflash/sysflash.h | 23 ----- boot/zephyr/main.c | 7 -- boot/zephyr/pm.yml | 13 --- 5 files changed, 26 insertions(+), 186 deletions(-) delete mode 100644 boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 568c28e45..e9f98f547 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,10 +49,6 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) -#include -#endif - #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" #endif @@ -1169,15 +1165,7 @@ boot_validated_swap_type(struct boot_loader_state *state, { int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); - bool upgrade_valid = false; - -#if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) - const struct flash_area *secondary_fa = - BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; - uint32_t vtable_addr = 0; - uint32_t *vtable = 0; - uint32_t reset_addr = 0; +#ifdef PM_S1_ADDRESS /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other * B1 slot S0 or S1) share the same secondary slot, we need to check * whether the update candidate in the secondary slot is intended for @@ -1185,36 +1173,34 @@ boot_validated_swap_type(struct boot_loader_state *state, * vector. Note that there are good reasons for not using img_num from * the swap info. */ + const struct flash_area *secondary_fa = + BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); + struct image_header *hdr = + (struct image_header *)secondary_fa->fa_off; if (hdr->ih_magic == IMAGE_MAGIC) { - vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - vtable = (uint32_t *)(vtable_addr); - reset_addr = vtable[1]; -#ifdef PM_S1_ADDRESS -#ifdef PM_CPUNET_B0N_ADDRESS - if(reset_addr < PM_CPUNET_B0N_ADDRESS) -#endif - { - const struct flash_area *primary_fa; - int rc = flash_area_open(flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), - BOOT_PRIMARY_SLOT), - &primary_fa); - - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } - /* Get start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off || - reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for this image - */ - return BOOT_SWAP_TYPE_NONE; - } - } -#endif /* PM_S1_ADDRESS */ + const struct flash_area *primary_fa; + uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + uint32_t *vtable = (uint32_t *)(vtable_addr); + uint32_t reset_addr = vtable[1]; + int rc = flash_area_open( + flash_area_id_from_multi_image_slot( + BOOT_CURR_IMG(state), + BOOT_PRIMARY_SLOT), + &primary_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + /* Get start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off || + reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for this image + */ + return BOOT_SWAP_TYPE_NONE; + } } -#endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ +#endif swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -1228,37 +1214,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } else { swap_type = BOOT_SWAP_TYPE_FAIL; } - } else { - upgrade_valid = true; - } - -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) - /* If the update is valid, and it targets the network core: perform the - * update and indicate to the caller of this function that no update is - * available - */ - if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { - uint32_t fw_size = hdr->ih_img_size; - - BOOT_LOG_INF("Starting network core update"); - int rc = pcd_network_core_update(vtable, fw_size); - - if (rc != 0) { - swap_type = BOOT_SWAP_TYPE_FAIL; - } else { - BOOT_LOG_INF("Done updating network core"); -#if defined(MCUBOOT_SWAP_USING_SCRATCH) || defined(MCUBOOT_SWAP_USING_MOVE) - /* swap_erase_trailer_sectors is undefined if upgrade only - * method is used. There is no need to erase sectors, because - * the image cannot be reverted. - */ - rc = swap_erase_trailer_sectors(state, - secondary_fa); -#endif - swap_type = BOOT_SWAP_TYPE_NONE; - } } -#endif /* CONFIG_SOC_NRF5340_CPUAPP */ } return swap_type; diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf deleted file mode 100644 index 7d3bc0bec..000000000 --- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf +++ /dev/null @@ -1,73 +0,0 @@ -CONFIG_SIZE_OPTIMIZATIONS=y - -CONFIG_SYSTEM_CLOCK_NO_WAIT=y -CONFIG_PM=n - -CONFIG_MAIN_STACK_SIZE=10240 -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -CONFIG_BOOT_MAX_IMG_SECTORS=2048 -CONFIG_BOOT_SIGNATURE_TYPE_RSA=y - -# Flash -CONFIG_FLASH=y -CONFIG_BOOT_ERASE_PROGRESSIVELY=y -CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y -CONFIG_FPROTECT=y - -# Serial -CONFIG_SERIAL=y -CONFIG_UART_LINE_CTRL=y - -# MCUBoot serial -CONFIG_GPIO=y -CONFIG_MCUBOOT_SERIAL=y -CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y -CONFIG_BOOT_SERIAL_CDC_ACM=y - -# Required by QSPI -CONFIG_NORDIC_QSPI_NOR=y -CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 -CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 - -# Required by USB and QSPI -CONFIG_MULTITHREADING=y - -# USB -CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n -CONFIG_USB_DEVICE_REMOTE_WAKEUP=n -CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor ASA" -CONFIG_USB_DEVICE_PRODUCT="Bootloader Thingy:53" -CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x5300 -CONFIG_USB_CDC_ACM=y - -# Decrease memory footprint -CONFIG_CBPRINTF_NANO=y -CONFIG_TIMESLICING=n -CONFIG_BOOT_BANNER=n -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n -CONFIG_LOG=n -CONFIG_ERRNO=n -CONFIG_PRINTK=n -CONFIG_RESET_ON_FATAL_ERROR=n -CONFIG_SPI=n -CONFIG_I2C=n -CONFIG_UART_NRFX=n - -# The following configurations are required to support simultaneous multi image update -CONFIG_PCD_APP=y -CONFIG_UPDATEABLE_IMAGE_NUMBER=2 -CONFIG_BOOT_UPGRADE_ONLY=y -# The network core cannot access external flash directly. The flash simulator must be used to -# provide a memory region that is used to forward the new firmware to the network core. -CONFIG_FLASH_SIMULATOR=y -CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y -CONFIG_FLASH_SIMULATOR_STATS=n - -# Enable custom command to erase settings partition. -CONFIG_ENABLE_MGMT_PERUSER=y -CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index b98e48bce..4eaf0309e 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -20,11 +20,6 @@ #elif (MCUBOOT_IMAGE_NUMBER == 2) -/* If B0 is present then two bootloaders are present, and we must use - * a single secondary slot for both primary slots. - */ -#ifdef PM_B0_ADDRESS - extern uint32_t _image_1_primary_slot_id[]; #define FLASH_AREA_IMAGE_PRIMARY(x) \ @@ -40,24 +35,6 @@ extern uint32_t _image_1_primary_slot_id[]; (x == 1) ? \ PM_MCUBOOT_SECONDARY_ID: \ 255 ) -#else - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) - -#endif /* PM_B0_ADDRESS */ - #endif #define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index fe37ff01d..df4c33937 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -91,10 +91,6 @@ const struct boot_uart_funcs boot_funcs = { #include #endif -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) -#include -#endif - /* CONFIG_LOG_MINIMAL is the legacy Kconfig property, * replaced by CONFIG_LOG_MODE_MINIMAL. */ @@ -591,9 +587,6 @@ int main(void) ; } -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) && defined(CONFIG_PCD_APP) - pcd_lock_ram(); -#endif #endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ ZEPHYR_BOOT_LOG_STOP(); diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml index 125b8813c..0c3a59154 100644 --- a/boot/zephyr/pm.yml +++ b/boot/zephyr/pm.yml @@ -72,16 +72,3 @@ mcuboot_pad: #ifdef CONFIG_FPROTECT align: {start: CONFIG_FPROTECT_BLOCK_SIZE} #endif - -#if (CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH) -mcuboot_primary_1: - region: ram_flash - size: CONFIG_NRF53_RAM_FLASH_SIZE -#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ - -#if (CONFIG_NRF53_MULTI_IMAGE_UPDATE) -mcuboot_secondary_1: - region: external_flash - size: CONFIG_NRF53_RAM_FLASH_SIZE - -#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ From 9b95757c1fddb1ae15dd61ff6702a886420e5db5 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 164/238] Revert "[nrf noup] treewide: add NCS partition manager support" This reverts commit 9555ca78469efc3ddc7cd2712edcae6de1befdb4. --- boot/bootutil/src/loader.c | 95 +++---------------------- boot/bootutil/src/swap_move.c | 13 ---- boot/bootutil/src/swap_scratch.c | 13 ---- boot/zephyr/CMakeLists.txt | 7 -- boot/zephyr/Kconfig | 2 - boot/zephyr/include/sysflash/sysflash.h | 48 ------------- boot/zephyr/include/target.h | 4 -- boot/zephyr/main.c | 45 ------------ boot/zephyr/pm.yml | 74 ------------------- boot/zephyr/prj.conf | 1 - ext/nrf/cc310_glue.h | 2 +- zephyr/module.yml | 3 +- 12 files changed, 11 insertions(+), 296 deletions(-) delete mode 100644 boot/zephyr/pm.yml diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index e9f98f547..bd3a7f09c 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -111,15 +111,6 @@ boot_read_image_headers(struct boot_loader_state *state, bool require_all, * * Failure to read any headers is a fatal error. */ -#ifdef PM_S1_ADDRESS - /* Patch needed for NCS. The primary slot of the second image - * (image 1) will not contain a valid image header until an upgrade - * of mcuboot has happened (filling S1 with the new version). - */ - if (BOOT_CURR_IMG(state) == 1 && i == 0) { - continue; - } -#endif /* PM_S1_ADDRESS */ if (i > 0 && !require_all) { return 0; } else { @@ -1065,24 +1056,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, goto out; } - uint32_t min_addr, max_addr; - -#ifdef PM_CPUNET_APP_ADDRESS - /* The primary slot for the network core is emulated in RAM. - * Its flash_area hasn't got relevant boundaries. - * Therfore need to override its boundaries for the check. - */ - if (BOOT_CURR_IMG(state) == 1) { - min_addr = PM_CPUNET_APP_ADDRESS; - max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; - } else -#endif - { - min_addr = pri_fa->fa_off; - max_addr = pri_fa->fa_off + pri_fa->fa_size; - } - - if (reset_value < min_addr || reset_value> (max_addr)) { + if (reset_value < pri_fa->fa_off || reset_value> (pri_fa->fa_off + pri_fa->fa_size)) { BOOT_LOG_ERR("Reset address of image in secondary slot is not in the primary slot"); BOOT_LOG_ERR("Erasing image from secondary slot"); @@ -1165,42 +1139,6 @@ boot_validated_swap_type(struct boot_loader_state *state, { int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); -#ifdef PM_S1_ADDRESS - /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other - * B1 slot S0 or S1) share the same secondary slot, we need to check - * whether the update candidate in the secondary slot is intended for - * image 0 or image 1 primary by looking at the address of the reset - * vector. Note that there are good reasons for not using img_num from - * the swap info. - */ - const struct flash_area *secondary_fa = - BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = - (struct image_header *)secondary_fa->fa_off; - - if (hdr->ih_magic == IMAGE_MAGIC) { - const struct flash_area *primary_fa; - uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - uint32_t *vtable = (uint32_t *)(vtable_addr); - uint32_t reset_addr = vtable[1]; - int rc = flash_area_open( - flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), - BOOT_PRIMARY_SLOT), - &primary_fa); - - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } - /* Get start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off || - reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for this image - */ - return BOOT_SWAP_TYPE_NONE; - } - } -#endif swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -2363,25 +2301,15 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } #ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT -#ifdef PM_S1_ADDRESS - /* Patch needed for NCS. Image 1 primary is the currently - * executing MCUBoot image, and is therefore already validated by NSIB and - * does not need to also be validated by MCUBoot. + FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL); + /* Check for all possible values is redundant in normal operation it + * is meant to prevent FI attack. */ - bool image_validated_by_nsib = BOOT_CURR_IMG(state) == 1; - if (!image_validated_by_nsib) -#endif - { - FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL); - /* Check for all possible values is redundant in normal operation it - * is meant to prevent FI attack. - */ - if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS) || - FIH_EQ(fih_rc, FIH_FAILURE) || - FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) { - FIH_SET(fih_rc, FIH_FAILURE); - goto out; - } + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS) || + FIH_EQ(fih_rc, FIH_FAILURE) || + FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; } #else /* Even if we're not re-validating the primary slot, we could be booting @@ -2398,16 +2326,11 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } #endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */ -#ifdef PM_S1_ADDRESS - if (!image_validated_by_nsib) -#endif - { rc = boot_update_hw_rollback_protection(state); if (rc != 0) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } - } rc = boot_add_shared_data(state, BOOT_PRIMARY_SLOT); if (rc != 0) { diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 5e6723bb6..111e82f05 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -259,18 +259,6 @@ static int app_max_sectors(struct boot_loader_state *state) int boot_slots_compatible(struct boot_loader_state *state) { -#ifdef PM_S1_ADDRESS - /* Patch needed for NCS. In this case, image 1 primary points to the other - * B1 slot (ie S0 or S1), and image 0 primary points to the app. - * With this configuration, image 0 and image 1 share the secondary slot. - * Hence, the primary slot of image 1 will be *smaller* than image 1's - * secondary slot. This is not allowed in upstream mcuboot, so we need - * this patch to allow it. Also, all of these checks are redundant when - * partition manager is in use, and since we have the same sector size - * in all of our flash. - */ - return 1; -#else size_t num_sectors_pri; size_t num_sectors_sec; size_t sector_sz_pri = 0; @@ -318,7 +306,6 @@ boot_slots_compatible(struct boot_loader_state *state) } return 1; -#endif /* PM_S1_ADDRESS */ } #define BOOT_LOG_SWAP_STATE(area, state) \ diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index a32eb8d87..66cbdce5f 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -170,18 +170,6 @@ boot_status_internal_off(const struct boot_status *bs, int elem_sz) int boot_slots_compatible(struct boot_loader_state *state) { -#ifdef PM_S1_ADDRESS - /* Patch needed for NCS. In this case, image 1 primary points to the other - * B1 slot (ie S0 or S1), and image 0 primary points to the app. - * With this configuration, image 0 and image 1 share the secondary slot. - * Hence, the primary slot of image 1 will be *smaller* than image 1's - * secondary slot. This is not allowed in upstream mcuboot, so we need - * this patch to allow it. Also, all of these checks are redundant when - * partition manager is in use, and since we have the same sector size - * in all of our flash. - */ - return 1; -#else size_t num_sectors_primary; size_t num_sectors_secondary; size_t sz0, sz1; @@ -267,7 +255,6 @@ boot_slots_compatible(struct boot_loader_state *state) } return 1; -#endif /* PM_S1_ADDRESS */ } #define BOOT_LOG_SWAP_STATE(area, state) \ diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index ddf9394d3..92999a687 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -295,13 +295,6 @@ if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "") endif() message("MCUBoot bootloader key file: ${KEY_FILE}") - set_property( - GLOBAL - PROPERTY - KEY_FILE - ${KEY_FILE} - ) - set(GENERATED_PUBKEY ${ZEPHYR_BINARY_DIR}/autogen-pubkey.c) add_custom_command( OUTPUT ${GENERATED_PUBKEY} diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 4b134b28f..effedfb4f 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -9,8 +9,6 @@ mainmenu "MCUboot configuration" comment "MCUboot-specific configuration options" -source "$(ZEPHYR_NRF_MODULE_DIR)/modules/mcuboot/boot/zephyr/Kconfig" - # Hidden option to mark a project as MCUboot config MCUBOOT default y diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 4eaf0309e..1952950b9 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -7,52 +7,6 @@ #ifndef __SYSFLASH_H__ #define __SYSFLASH_H__ -#if USE_PARTITION_MANAGER -#include -#include - -#ifndef CONFIG_SINGLE_APPLICATION_SLOT - -#if (MCUBOOT_IMAGE_NUMBER == 1) - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID - -#elif (MCUBOOT_IMAGE_NUMBER == 2) - -extern uint32_t _image_1_primary_slot_id[]; - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - (uint32_t)_image_1_primary_slot_id : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - 255 ) -#endif -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID - -#else /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID -/* NOTE: Scratch parition is not used by single image DFU but some of - * functions in common files reference it, so the definitions has been - * provided to allow compilation of common units. - */ -#define FLASH_AREA_IMAGE_SCRATCH 0 - -#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#else - -#include #include #include #include @@ -111,6 +65,4 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ -#endif /* USE_PARTITION_MANAGER */ - #endif /* __SYSFLASH_H__ */ diff --git a/boot/zephyr/include/target.h b/boot/zephyr/include/target.h index 40287d515..9bbfd4b19 100644 --- a/boot/zephyr/include/target.h +++ b/boot/zephyr/include/target.h @@ -8,8 +8,6 @@ #ifndef H_TARGETS_TARGET_ #define H_TARGETS_TARGET_ -#ifndef USE_PARTITION_MANAGER - #if defined(MCUBOOT_TARGET_CONFIG) /* * Target-specific definitions are permitted in legacy cases that @@ -47,6 +45,4 @@ #error "Target support is incomplete; cannot build mcuboot." #endif -#endif /* ifndef USE_PARTITION_MANAGER */ - #endif /* H_TARGETS_TARGET_ */ diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index df4c33937..95da276bd 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -69,10 +69,6 @@ #endif /* CONFIG_SOC_FAMILY_ESPRESSIF_ESP32 */ -#ifdef CONFIG_FW_INFO -#include -#endif - #ifdef CONFIG_MCUBOOT_SERIAL #include "boot_serial/boot_serial.h" #include "serial_adapter/serial_adapter.h" @@ -133,11 +129,6 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); * !defined(ZEPHYR_LOG_MODE_MINIMAL) */ -#if USE_PARTITION_MANAGER && CONFIG_FPROTECT -#include -#include -#endif - BOOT_LOG_MODULE_REGISTER(mcuboot); void os_heap_init(void); @@ -196,19 +187,6 @@ static void do_boot(struct boot_rsp *rsp) /* Disable the USB to prevent it from firing interrupts */ usb_disable(); #endif - -#if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - bool provided = fw_info_ext_api_provide(fw_info_find((uint32_t)vt), true); - -#ifdef PM_S0_ADDRESS - /* Only fail if the immutable bootloader is present. */ - if (!provided) { - BOOT_LOG_ERR("Failed to provide EXT_APIs\n"); - return; - } -#endif -#endif - #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ @@ -567,30 +545,7 @@ int main(void) mcuboot_status_change(MCUBOOT_STATUS_BOOTABLE_IMAGE_FOUND); -#if USE_PARTITION_MANAGER && CONFIG_FPROTECT - -#ifdef PM_S1_ADDRESS -/* MCUBoot is stored in either S0 or S1, protect both */ -#define PROTECT_SIZE (PM_MCUBOOT_PRIMARY_ADDRESS - PM_S0_ADDRESS) -#define PROTECT_ADDR PM_S0_ADDRESS -#else -/* There is only one instance of MCUBoot */ -#define PROTECT_SIZE (PM_MCUBOOT_PRIMARY_ADDRESS - PM_MCUBOOT_ADDRESS) -#define PROTECT_ADDR PM_MCUBOOT_ADDRESS -#endif - - rc = fprotect_area(PROTECT_ADDR, PROTECT_SIZE); - - if (rc != 0) { - BOOT_LOG_ERR("Protect mcuboot flash failed, cancel startup."); - while (1) - ; - } - -#endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ - ZEPHYR_BOOT_LOG_STOP(); - do_boot(&rsp); mcuboot_status_change(MCUBOOT_STATUS_BOOT_FAILED); diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml deleted file mode 100644 index 0c3a59154..000000000 --- a/boot/zephyr/pm.yml +++ /dev/null @@ -1,74 +0,0 @@ -#include - -mcuboot: - size: CONFIG_PM_PARTITION_SIZE_MCUBOOT - placement: - before: [mcuboot_primary] - -mcuboot_primary_app: - # All images to be placed in MCUboot's slot 0 should be placed in this - # partition - span: [app] - -mcuboot_primary: - span: [mcuboot_pad, mcuboot_primary_app] - -# Partition for secondary slot is not created if building in single application -# slot configuration. -#if !defined(CONFIG_SINGLE_APPLICATION_SLOT) && !defined(CONFIG_BOOT_DIRECT_XIP) -mcuboot_secondary: - share_size: [mcuboot_primary] -#if defined(CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY) - region: external_flash - placement: - align: {start: 4} -#else - placement: - align: {start: CONFIG_FPROTECT_BLOCK_SIZE} - align_next: CONFIG_FPROTECT_BLOCK_SIZE # Ensure that the next partition does not interfere with this image - after: mcuboot_primary -#endif /* CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY */ - -#endif /* !defined(CONFIG_SINGLE_APPLICATION_SLOT) && !defined(CONFIG_BOOT_DIRECT_XIP) */ - -#if CONFIG_BOOT_DIRECT_XIP - -# Direct XIP is enabled, reserve area for metadata (padding) and name the -# partition so that its clear that it is not the secondary slot, but the direct -# XIP alternative. - -mcuboot_secondary_pad: - share_size: mcuboot_pad - placement: - after: mcuboot_primary - align: {start: CONFIG_FPROTECT_BLOCK_SIZE} - -mcuboot_secondary_app: - share_size: mcuboot_primary_app - placement: - after: mcuboot_secondary_pad - -mcuboot_secondary: - span: [mcuboot_secondary_pad, mcuboot_secondary_app] - -#endif /* CONFIG_BOOT_DIRECT_XIP */ - -#if CONFIG_BOOT_SWAP_USING_SCRATCH -mcuboot_scratch: - size: CONFIG_PM_PARTITION_SIZE_MCUBOOT_SCRATCH - placement: - after: app - align: {start: CONFIG_FPROTECT_BLOCK_SIZE} -#endif /* CONFIG_BOOT_SWAP_USING_SCRATCH */ - -# Padding placed before image to boot. This reserves space for the MCUboot image header -# and it ensures that the boot image gets linked with the correct address offset in flash. -mcuboot_pad: - # MCUboot pad must be placed before the primary application partition. - # The primary application partition includes the secure firmware if present. - size: CONFIG_PM_PARTITION_SIZE_MCUBOOT_PAD - placement: - before: [mcuboot_primary_app] -#ifdef CONFIG_FPROTECT - align: {start: CONFIG_FPROTECT_BLOCK_SIZE} -#endif diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 23b5f3b93..58cb2ae35 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -19,7 +19,6 @@ CONFIG_BOOT_BOOTSTRAP=n # CONFIG_TINYCRYPT_SHA256 is not set CONFIG_FLASH=y -CONFIG_FPROTECT=y ### Various Zephyr boards enable features that we don't want. # CONFIG_BT is not set diff --git a/ext/nrf/cc310_glue.h b/ext/nrf/cc310_glue.h index 22eb94911..ed3ed5c00 100644 --- a/ext/nrf/cc310_glue.h +++ b/ext/nrf/cc310_glue.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include /* diff --git a/zephyr/module.yml b/zephyr/module.yml index 9360dbf70..014a21956 100644 --- a/zephyr/module.yml +++ b/zephyr/module.yml @@ -1,6 +1,5 @@ samples: - boot/zephyr build: - cmake-ext: True - kconfig-ext: True + cmake: ./boot/bootutil/zephyr sysbuild-cmake: boot/zephyr/sysbuild From bfe238c7c42e2e5d3f9e9d6da53810b68dc5d23d Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 165/238] Revert "[nrf noup] boards: thingy91x: add board config" This reverts commit 916a9dcb137df96c435cc1b63b20ba265957ae51. --- .../boards/thingy91x_nrf5340_cpuapp.conf | 54 ------------------- boot/zephyr/boards/thingy91x_nrf9151.conf | 8 --- 2 files changed, 62 deletions(-) delete mode 100644 boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf delete mode 100644 boot/zephyr/boards/thingy91x_nrf9151.conf diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf deleted file mode 100644 index 72dfa7fca..000000000 --- a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf +++ /dev/null @@ -1,54 +0,0 @@ -# MCUBoot settings -CONFIG_BOOT_MAX_IMG_SECTORS=110 - -# MCUboot serial recovery -CONFIG_MCUBOOT_SERIAL=y - -# Disable Zephyr console -CONFIG_LOG=n -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_UART_CONSOLE=n - -# Serial -CONFIG_SERIAL=y -CONFIG_UART_NRFX=y -CONFIG_UART_INTERRUPT_DRIVEN=y -CONFIG_UART_LINE_CTRL=y - -# MCUboot serial recovery -CONFIG_GPIO=y -CONFIG_MCUBOOT_SERIAL=y -CONFIG_BOOT_SERIAL_CDC_ACM=y - -# Required by USB -CONFIG_MULTITHREADING=y - -# USB -CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_PRODUCT="MCUBOOT" -CONFIG_USB_CDC_ACM=y -CONFIG_USB_COMPOSITE_DEVICE=y -CONFIG_USB_MASS_STORAGE=n -CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" -CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x520F - -CONFIG_BOOT_SERIAL_BOOT_MODE=y - -CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x13E00 - -# The following configurations are required to support simultaneous multi image update -CONFIG_PCD_APP=y -CONFIG_UPDATEABLE_IMAGE_NUMBER=2 -CONFIG_BOOT_UPGRADE_ONLY=y -# The network core cannot access external flash directly. The flash simulator must be used to -# provide a memory region that is used to forward the new firmware to the network core. -CONFIG_FLASH_SIMULATOR=y -CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y -CONFIG_FLASH_SIMULATOR_STATS=n - -CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y -CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y - -CONFIG_NRF53_RECOVERY_NETWORK_CORE=y diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf deleted file mode 100644 index 33cd3301c..000000000 --- a/boot/zephyr/boards/thingy91x_nrf9151.conf +++ /dev/null @@ -1,8 +0,0 @@ -# MCUBoot settings -CONFIG_BOOT_MAX_IMG_SECTORS=512 - -CONFIG_SPI=y -CONFIG_SPI_NOR=y -CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 -CONFIG_SPI_NOR_SFDP_DEVICETREE=y -CONFIG_MULTITHREADING=y From dd75051f90bea4b1b862e068aefcfc39f5f24df0 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 166/238] Revert "[nrf noup] zephyr: Restore default RTC user channel count" This reverts commit cffdc5207003743f1951e2d4a84cc9e9dcc35eee. --- boot/zephyr/prj.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 58cb2ae35..851c133ec 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -35,4 +35,3 @@ CONFIG_MCUBOOT_LOG_LEVEL_INF=y CONFIG_CBPRINTF_NANO=y ### Use the minimal C library to reduce flash usage CONFIG_MINIMAL_LIBC=y -CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 From 7ea58bebbf639e0da01a604d2f57b497650652e1 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 167/238] Revert "[nrf noup] boards: add support for Thingy:91" This reverts commit a53f78d7bde6697eb3eb938a993ad2970759d952. --- boot/zephyr/boards/thingy91_nrf52840.conf | 34 ----------------------- boot/zephyr/boards/thingy91_nrf9160.conf | 13 --------- 2 files changed, 47 deletions(-) delete mode 100644 boot/zephyr/boards/thingy91_nrf52840.conf delete mode 100644 boot/zephyr/boards/thingy91_nrf9160.conf diff --git a/boot/zephyr/boards/thingy91_nrf52840.conf b/boot/zephyr/boards/thingy91_nrf52840.conf deleted file mode 100644 index c0d183401..000000000 --- a/boot/zephyr/boards/thingy91_nrf52840.conf +++ /dev/null @@ -1,34 +0,0 @@ -# Disable Zephyr console -CONFIG_LOG=n -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_UART_CONSOLE=n - -# The build won't fit on the partition allocated for it without size -# optimizations. -CONFIG_SIZE_OPTIMIZATIONS=y -CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x12000 - -# Serial -CONFIG_SERIAL=y -CONFIG_UART_NRFX=y -CONFIG_UART_INTERRUPT_DRIVEN=y -CONFIG_UART_LINE_CTRL=y - -# MCUboot serial recovery -CONFIG_GPIO=y -CONFIG_MCUBOOT_SERIAL=y -CONFIG_BOOT_SERIAL_CDC_ACM=y - -# Required by USB -CONFIG_MULTITHREADING=y - -# USB -CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_PRODUCT="MCUBOOT" -CONFIG_USB_CDC_ACM=y -CONFIG_USB_COMPOSITE_DEVICE=y -CONFIG_USB_MASS_STORAGE=n -CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" -CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x520F diff --git a/boot/zephyr/boards/thingy91_nrf9160.conf b/boot/zephyr/boards/thingy91_nrf9160.conf deleted file mode 100644 index 1bf2e424d..000000000 --- a/boot/zephyr/boards/thingy91_nrf9160.conf +++ /dev/null @@ -1,13 +0,0 @@ -# Disable Zephyr console -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_UART_CONSOLE=n - -# Disable Flash protection -CONFIG_FPROTECT=n - -# MCUBoot settings -CONFIG_BOOT_MAX_IMG_SECTORS=256 - -# MCUboot serial recovery -CONFIG_MCUBOOT_SERIAL=y From ae0e3ea3e8eb72bc3008f866b6364189d799472b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 168/238] Revert "[nrf noup] zephyr: add 'minimal' configuration files" This reverts commit cd1c995a5d48d182747449ad5cad16ae3c981f67. --- .../nrf5340dk_nrf5340_cpuapp_minimal.conf | 13 ------ boot/zephyr/prj_minimal.conf | 41 ------------------- 2 files changed, 54 deletions(-) delete mode 100644 boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf delete mode 100644 boot/zephyr/prj_minimal.conf diff --git a/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf b/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf deleted file mode 100644 index dd5468106..000000000 --- a/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright (c) 2021 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - -# CC3xx is currently not used for nrf53 -CONFIG_HW_CC3XX=n -CONFIG_NRF_CC3XX_PLATFORM=n - -# Required for kernel operation -CONFIG_CLOCK_CONTROL=y -CONFIG_SYS_CLOCK_EXISTS=y diff --git a/boot/zephyr/prj_minimal.conf b/boot/zephyr/prj_minimal.conf deleted file mode 100644 index 1f90e708b..000000000 --- a/boot/zephyr/prj_minimal.conf +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright (c) 2021 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - -CONFIG_MAIN_STACK_SIZE=10240 -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -CONFIG_FLASH=y -CONFIG_FPROTECT=y -CONFIG_PM=n - -CONFIG_BOOT_SWAP_SAVE_ENCTLV=n -CONFIG_BOOT_ENCRYPT_IMAGE=n - -CONFIG_BOOT_BOOTSTRAP=n -CONFIG_BOOT_UPGRADE_ONLY=n - -### Minimal Configurations ### -CONFIG_BOOT_USE_MIN_PARTITION_SIZE=y -CONFIG_ASSERT=n -CONFIG_BOOT_BANNER=n -CONFIG_CLOCK_CONTROL=n -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_GPIO=n -CONFIG_KERNEL_MEM_POOL=n -CONFIG_LOG=n -CONFIG_MINIMAL_LIBC_CALLOC=n -CONFIG_MINIMAL_LIBC_MALLOC=n -CONFIG_MINIMAL_LIBC_REALLOCARRAY=n -CONFIG_NCS_SAMPLES_DEFAULTS=n -CONFIG_NO_RUNTIME_CHECKS=y -CONFIG_NRF_RTC_TIMER=n -CONFIG_PRINTK=n -CONFIG_SECURE_BOOT_DEBUG=n -CONFIG_SERIAL=n -CONFIG_SIZE_OPTIMIZATIONS=y -CONFIG_SYS_CLOCK_EXISTS=n -CONFIG_UART_CONSOLE=n From 28859c14d80843dbd6ffe7c0db5f784bb62da39c Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 169/238] Revert "[nrf noup] zephyr: Remove duplication from cmake" This reverts commit 312ba86aa87e95563635536332e704d30c750a95. --- boot/zephyr/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 92999a687..45548e0c3 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -42,6 +42,8 @@ if(NOT EXISTS ${NRFXLIB_DIR}) To use the tinycrypt set `CONFIG_BOOT_ECDSA_TINYCRYPT` to y. ------------------------------------------------------------------------") endif() +# Don't include this if we are using west + add_subdirectory(${NRFXLIB_DIR} ${PROJECT_BINARY_DIR}/nrfxlib) endif() zephyr_library_include_directories( From a539a7828b838e0af77c5c570a7e84039a9fc1cf Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 4 Oct 2024 10:46:41 +0200 Subject: [PATCH 170/238] Revert "[nrf noup] github: Add a commit tags check workflow" This reverts commit 195145ba45afb3a7295cfb8a186a141a1520c2f3. --- .github/workflows/commit-tags.yml | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 .github/workflows/commit-tags.yml diff --git a/.github/workflows/commit-tags.yml b/.github/workflows/commit-tags.yml deleted file mode 100644 index 9e0323f94..000000000 --- a/.github/workflows/commit-tags.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Commit tags - -on: pull_request - -jobs: - commit_tags: - runs-on: ubuntu-22.04 - name: Run commit tags checks on patch series (PR) - steps: - - name: Update PATH for west - run: | - echo "$HOME/.local/bin" >> $GITHUB_PATH - - - name: Checkout the code - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - - - name: Install python dependencies - run: | - pip3 install setuptools - pip3 install wheel - pip3 install gitlint - - - name: Run the commit tags - uses: nrfconnect/action-commit-tags@main - with: - target: '.' - baserev: origin/${{ github.base_ref }} - revrange: 'none' From 00f58607a396fe4da36acadfbdd7586772d5aab5 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Tue, 10 Oct 2023 15:51:54 +0200 Subject: [PATCH 171/238] [nrf noup] github: Add a commit tags check workflow Use the generic commit-tags action to provide sauce tag checks. Signed-off-by: Carles Cufi (cherry picked from commit 786e351400566f69289eace77f215a6376b851d9) --- .github/workflows/commit-tags.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/commit-tags.yml diff --git a/.github/workflows/commit-tags.yml b/.github/workflows/commit-tags.yml new file mode 100644 index 000000000..9e0323f94 --- /dev/null +++ b/.github/workflows/commit-tags.yml @@ -0,0 +1,31 @@ +name: Commit tags + +on: pull_request + +jobs: + commit_tags: + runs-on: ubuntu-22.04 + name: Run commit tags checks on patch series (PR) + steps: + - name: Update PATH for west + run: | + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Checkout the code + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Install python dependencies + run: | + pip3 install setuptools + pip3 install wheel + pip3 install gitlint + + - name: Run the commit tags + uses: nrfconnect/action-commit-tags@main + with: + target: '.' + baserev: origin/${{ github.base_ref }} + revrange: 'none' From 6bc65a9a5494e77a7d930d7ee7a9883d36207332 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Tue, 26 Mar 2019 15:42:38 +0100 Subject: [PATCH 172/238] [nrf noup] zephyr: Remove duplication from cmake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the `add_subdirectory` of nrfxlib it will still check that the nrfxlib is located outside the mcuboot directory. Signed-off-by: Sigvart Hovland Signed-off-by: Andrzej Puzdrowski Signed-off-by: Martí Bolívar Signed-off-by: Emil Obalski Signed-off-by: Andrzej Puzdrowski Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 5c94965afb7c8f8d1866ce2079e72f80bc889d1a) --- boot/zephyr/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index d02f93a40..89d76e991 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -42,8 +42,6 @@ if(NOT EXISTS ${NRFXLIB_DIR}) To use the tinycrypt set `CONFIG_BOOT_ECDSA_TINYCRYPT` to y. ------------------------------------------------------------------------") endif() -# Don't include this if we are using west - add_subdirectory(${NRFXLIB_DIR} ${PROJECT_BINARY_DIR}/nrfxlib) endif() zephyr_library_include_directories( From bee94754baf89c4b81858ad2cdc5f171a1ea800c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 3 Sep 2021 14:38:54 -0700 Subject: [PATCH 173/238] [nrf noup] zephyr: add 'minimal' configuration files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add prj_minimal.conf, a Kconfig fragment to be used for minimally sized image production. The minimal fragment has been simplified for only external crypto. Move partition sizing into Kconfig to be consistent with the method used by b0. Using this fragment with prj_minimal.conf makes MCUboot < 16kB for all nRF devices (9160 still needs 32kB partition). Ref: NCSDK-6704 Signed-off-by: Stephen Stauts Signed-off-by: Martí Bolívar Signed-off-by: Sebastian Bøe Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 64740f7c95ca8b7b090086077876670edb95716b) --- .../nrf5340dk_nrf5340_cpuapp_minimal.conf | 13 ++++++ boot/zephyr/prj_minimal.conf | 41 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf create mode 100644 boot/zephyr/prj_minimal.conf diff --git a/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf b/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf new file mode 100644 index 000000000..dd5468106 --- /dev/null +++ b/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf @@ -0,0 +1,13 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# CC3xx is currently not used for nrf53 +CONFIG_HW_CC3XX=n +CONFIG_NRF_CC3XX_PLATFORM=n + +# Required for kernel operation +CONFIG_CLOCK_CONTROL=y +CONFIG_SYS_CLOCK_EXISTS=y diff --git a/boot/zephyr/prj_minimal.conf b/boot/zephyr/prj_minimal.conf new file mode 100644 index 000000000..1f90e708b --- /dev/null +++ b/boot/zephyr/prj_minimal.conf @@ -0,0 +1,41 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +CONFIG_MAIN_STACK_SIZE=10240 +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +CONFIG_FLASH=y +CONFIG_FPROTECT=y +CONFIG_PM=n + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_ENCRYPT_IMAGE=n + +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_BOOT_UPGRADE_ONLY=n + +### Minimal Configurations ### +CONFIG_BOOT_USE_MIN_PARTITION_SIZE=y +CONFIG_ASSERT=n +CONFIG_BOOT_BANNER=n +CONFIG_CLOCK_CONTROL=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_GPIO=n +CONFIG_KERNEL_MEM_POOL=n +CONFIG_LOG=n +CONFIG_MINIMAL_LIBC_CALLOC=n +CONFIG_MINIMAL_LIBC_MALLOC=n +CONFIG_MINIMAL_LIBC_REALLOCARRAY=n +CONFIG_NCS_SAMPLES_DEFAULTS=n +CONFIG_NO_RUNTIME_CHECKS=y +CONFIG_NRF_RTC_TIMER=n +CONFIG_PRINTK=n +CONFIG_SECURE_BOOT_DEBUG=n +CONFIG_SERIAL=n +CONFIG_SIZE_OPTIMIZATIONS=y +CONFIG_SYS_CLOCK_EXISTS=n +CONFIG_UART_CONSOLE=n From 49e2872fb37664823a4fd56ba0c03807bd5dc9ec Mon Sep 17 00:00:00 2001 From: Bernt Johan Damslora Date: Fri, 20 Sep 2019 18:25:41 +0200 Subject: [PATCH 174/238] [nrf noup] boards: add support for Thingy:91 Adds project configurations for the two systems on the Thingy:91 (PCA-20035) board. The bootloader that is factory-programmed on thing91 does not support ECDSA signature type. Hence this commit also sets the signature type to RSA for applications built for Thingy:91. Signed-off-by: Bernt Johan Damslora Signed-off-by: Sigvart Hovland Signed-off-by: Jon Helge Nistad Signed-off-by: Balaji Srinivasan Signed-off-by: Robert Lubos Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Marek Pieta Signed-off-by: Dominik Ermel (cherry picked from commit de32681f8b9f6c27243a010752a9230662bf4db4) --- boot/zephyr/boards/thingy91_nrf52840.conf | 34 +++++++++++++++++++++++ boot/zephyr/boards/thingy91_nrf9160.conf | 13 +++++++++ 2 files changed, 47 insertions(+) create mode 100644 boot/zephyr/boards/thingy91_nrf52840.conf create mode 100644 boot/zephyr/boards/thingy91_nrf9160.conf diff --git a/boot/zephyr/boards/thingy91_nrf52840.conf b/boot/zephyr/boards/thingy91_nrf52840.conf new file mode 100644 index 000000000..c0d183401 --- /dev/null +++ b/boot/zephyr/boards/thingy91_nrf52840.conf @@ -0,0 +1,34 @@ +# Disable Zephyr console +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n + +# The build won't fit on the partition allocated for it without size +# optimizations. +CONFIG_SIZE_OPTIMIZATIONS=y +CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x12000 + +# Serial +CONFIG_SERIAL=y +CONFIG_UART_NRFX=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_LINE_CTRL=y + +# MCUboot serial recovery +CONFIG_GPIO=y +CONFIG_MCUBOOT_SERIAL=y +CONFIG_BOOT_SERIAL_CDC_ACM=y + +# Required by USB +CONFIG_MULTITHREADING=y + +# USB +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_PRODUCT="MCUBOOT" +CONFIG_USB_CDC_ACM=y +CONFIG_USB_COMPOSITE_DEVICE=y +CONFIG_USB_MASS_STORAGE=n +CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" +CONFIG_USB_DEVICE_VID=0x1915 +CONFIG_USB_DEVICE_PID=0x520F diff --git a/boot/zephyr/boards/thingy91_nrf9160.conf b/boot/zephyr/boards/thingy91_nrf9160.conf new file mode 100644 index 000000000..1bf2e424d --- /dev/null +++ b/boot/zephyr/boards/thingy91_nrf9160.conf @@ -0,0 +1,13 @@ +# Disable Zephyr console +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n + +# Disable Flash protection +CONFIG_FPROTECT=n + +# MCUBoot settings +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +# MCUboot serial recovery +CONFIG_MCUBOOT_SERIAL=y From 93bb567b8a3d8a708d5f09e09d0e251c3e43c235 Mon Sep 17 00:00:00 2001 From: Damian Krolik Date: Mon, 21 Mar 2022 13:44:27 +0100 Subject: [PATCH 175/238] [nrf noup] zephyr: Restore default RTC user channel count The default value of CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT for nRF52 SOCs has been changed from 0 to 3, but it makes MCUBoot get stuck on erasing flash pages when swapping two images. Restore the previous value until the RTC issue is resolved (see NCSDK-14427) Signed-off-by: Damian Krolik Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit a01d30a9906ee0b874f48c8f12f05185cc4e4a8e) --- boot/zephyr/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 851c133ec..58cb2ae35 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -35,3 +35,4 @@ CONFIG_MCUBOOT_LOG_LEVEL_INF=y CONFIG_CBPRINTF_NANO=y ### Use the minimal C library to reduce flash usage CONFIG_MINIMAL_LIBC=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 From c473f8ed1c5e258294fd3da20beb210292ecc9b8 Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Fri, 8 Dec 2023 13:18:12 +0100 Subject: [PATCH 176/238] [nrf noup] boards: thingy91x: add board config This patch adds board configuration for the Thingy:91 X. Signed-off-by: Maximilian Deubel (cherry picked from commit 3c2f2ff12bc20625cd65730b6036d061de4da5f7) --- .../boards/thingy91x_nrf5340_cpuapp.conf | 54 +++++++++++++++++++ boot/zephyr/boards/thingy91x_nrf9151.conf | 8 +++ 2 files changed, 62 insertions(+) create mode 100644 boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf create mode 100644 boot/zephyr/boards/thingy91x_nrf9151.conf diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf new file mode 100644 index 000000000..72dfa7fca --- /dev/null +++ b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf @@ -0,0 +1,54 @@ +# MCUBoot settings +CONFIG_BOOT_MAX_IMG_SECTORS=110 + +# MCUboot serial recovery +CONFIG_MCUBOOT_SERIAL=y + +# Disable Zephyr console +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n + +# Serial +CONFIG_SERIAL=y +CONFIG_UART_NRFX=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_LINE_CTRL=y + +# MCUboot serial recovery +CONFIG_GPIO=y +CONFIG_MCUBOOT_SERIAL=y +CONFIG_BOOT_SERIAL_CDC_ACM=y + +# Required by USB +CONFIG_MULTITHREADING=y + +# USB +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_PRODUCT="MCUBOOT" +CONFIG_USB_CDC_ACM=y +CONFIG_USB_COMPOSITE_DEVICE=y +CONFIG_USB_MASS_STORAGE=n +CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" +CONFIG_USB_DEVICE_VID=0x1915 +CONFIG_USB_DEVICE_PID=0x520F + +CONFIG_BOOT_SERIAL_BOOT_MODE=y + +CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x13E00 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 +CONFIG_BOOT_UPGRADE_ONLY=y +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y + +CONFIG_NRF53_RECOVERY_NETWORK_CORE=y diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf new file mode 100644 index 000000000..33cd3301c --- /dev/null +++ b/boot/zephyr/boards/thingy91x_nrf9151.conf @@ -0,0 +1,8 @@ +# MCUBoot settings +CONFIG_BOOT_MAX_IMG_SECTORS=512 + +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_SPI_NOR_SFDP_DEVICETREE=y +CONFIG_MULTITHREADING=y From 6facec9d2d89d853302c994c96d21134d4c23b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Wed, 12 Dec 2018 08:59:47 +0100 Subject: [PATCH 177/238] [nrf noup] treewide: add NCS partition manager support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partition Manager is an nRF Connect SDK component which uses yaml files to resolve flash partition placement with a holistic view of the device. This component's MCUboot portions began life as upstream mcuboot PR#430. This added support for being built as a sub image from the downstream Nordic patch set for a zephyr multi image build system (mcuboot 430 was combined with effor submitted to upstream zephyr as PR#13672, which was ultimately reworked after being rejected for mainline at the ELCE 2019 conference in Lyon). It has since evolved over time. This is the version that will go into NCS v1.3. It features: - page size aligned partitions for all partitions used by mcuboot. - image swaps without scratch partitions Add support for configurations where there exists two primary slots but only one secondary slot, which is shared. These two primary slots are the regular application and B1. B1 can be either S0 or S1 depending on the state of the device. Decide where an upgrade should be stored by looking at the vector table. Provide update candidates for both s0 and s1. These candidates must be signed with mcuboot after being signed by b0. Additional notes: - we make update.hex without trailer data This is needed for serial recovery to work using hex files. Prior to this the update.hex got TLV data at the end of the partition, which caused many blank pages to be included, which made it hard to use in a serial recovery scheme. Instead, make update.hex without TLV data at the end, and provide a new file test_update.hex which contains the TLV data, and can be directly flashed to test the upgrade procedure. - we use a function for signing the application as future-proofing for when other components must be signed as well - this includes an update to single image applications that enables support for partition manager; when single image DFU is used, a scratch partition is not needed. - In NCS, image 1 primary slot is the upgrade bank for mcuboot (IE S0 or S1 depending on the active slot). It is not required that this slot contains any valid data. - The nRF boards all have a single flash page size, and partition manager deals with the size of the update partitions and so on, so we must skip a boot_slots_compatible() check to avoid getting an error. - There is no need to verify the target when using partition manager. - We lock mcuboot using fprotect before jumping, to enable the secure boot property of the system. - Call fw_info_ext_api_provide() before booting if EXT_API_PROVIDE EXT_API is enabled. This is relevant only when the immutable bootloader has booted mcuboot. Signed-off-by: Håkon Øye Amundsen Signed-off-by: Øyvind Rønningstad Signed-off-by: Sebastian Bøe Signed-off-by: Sigvart Hovland Signed-off-by: Martí Bolívar Signed-off-by: Torsten Rasmussen Signed-off-by: Andrzej Głąbek Signed-off-by: Robert Lubos Signed-off-by: Andrzej Puzdrowski Signed-off-by: Emil Obalski Signed-off-by: Pawel Dunaj Signed-off-by: Ioannis Glaropoulos Signed-off-by: Johann Fischer Signed-off-by: Vidar Berg Signed-off-by: Draus, Sebastian Signed-off-by: Trond Einar Snekvik Signed-off-by: Jamie McCrae Signed-off-by: Joakim Andersson Signed-off-by: Georgios Vasilakis Signed-off-by: Dominik Ermel (cherry picked from commit 518617a4921c66e637073753370974743127412c) --- boot/bootutil/src/loader.c | 95 ++++++++++++++++++++++--- boot/bootutil/src/swap_move.c | 13 ++++ boot/bootutil/src/swap_scratch.c | 13 ++++ boot/zephyr/CMakeLists.txt | 7 ++ boot/zephyr/Kconfig | 2 + boot/zephyr/include/sysflash/sysflash.h | 48 +++++++++++++ boot/zephyr/include/target.h | 4 ++ boot/zephyr/main.c | 45 ++++++++++++ boot/zephyr/pm.yml | 74 +++++++++++++++++++ boot/zephyr/prj.conf | 1 + ext/nrf/cc310_glue.h | 2 +- zephyr/module.yml | 3 +- 12 files changed, 296 insertions(+), 11 deletions(-) create mode 100644 boot/zephyr/pm.yml diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 3f0793388..9369445d1 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -128,6 +128,15 @@ boot_read_image_headers(struct boot_loader_state *state, bool require_all, * * Failure to read any headers is a fatal error. */ +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. The primary slot of the second image + * (image 1) will not contain a valid image header until an upgrade + * of mcuboot has happened (filling S1 with the new version). + */ + if (BOOT_CURR_IMG(state) == 1 && i == 0) { + continue; + } +#endif /* PM_S1_ADDRESS */ if (i > 0 && !require_all) { return 0; } else { @@ -1108,7 +1117,24 @@ boot_validate_slot(struct boot_loader_state *state, int slot, goto out; } - if (reset_value < pri_fa->fa_off || reset_value> (pri_fa->fa_off + pri_fa->fa_size)) { + uint32_t min_addr, max_addr; + +#ifdef PM_CPUNET_APP_ADDRESS + /* The primary slot for the network core is emulated in RAM. + * Its flash_area hasn't got relevant boundaries. + * Therfore need to override its boundaries for the check. + */ + if (BOOT_CURR_IMG(state) == 1) { + min_addr = PM_CPUNET_APP_ADDRESS; + max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; + } else +#endif + { + min_addr = pri_fa->fa_off; + max_addr = pri_fa->fa_off + pri_fa->fa_size; + } + + if (reset_value < min_addr || reset_value> (max_addr)) { BOOT_LOG_ERR("Reset address of image in secondary slot is not in the primary slot"); BOOT_LOG_ERR("Erasing image from secondary slot"); @@ -1191,6 +1217,42 @@ boot_validated_swap_type(struct boot_loader_state *state, { int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other + * B1 slot S0 or S1) share the same secondary slot, we need to check + * whether the update candidate in the secondary slot is intended for + * image 0 or image 1 primary by looking at the address of the reset + * vector. Note that there are good reasons for not using img_num from + * the swap info. + */ + const struct flash_area *secondary_fa = + BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); + struct image_header *hdr = + (struct image_header *)secondary_fa->fa_off; + + if (hdr->ih_magic == IMAGE_MAGIC) { + const struct flash_area *primary_fa; + uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + uint32_t *vtable = (uint32_t *)(vtable_addr); + uint32_t reset_addr = vtable[1]; + int rc = flash_area_open( + flash_area_id_from_multi_image_slot( + BOOT_CURR_IMG(state), + BOOT_PRIMARY_SLOT), + &primary_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + /* Get start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off || + reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for this image + */ + return BOOT_SWAP_TYPE_NONE; + } + } +#endif swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -2422,15 +2484,25 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } #ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT - FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL); - /* Check for all possible values is redundant in normal operation it - * is meant to prevent FI attack. +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. Image 1 primary is the currently + * executing MCUBoot image, and is therefore already validated by NSIB and + * does not need to also be validated by MCUBoot. */ - if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS) || - FIH_EQ(fih_rc, FIH_FAILURE) || - FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) { - FIH_SET(fih_rc, FIH_FAILURE); - goto out; + bool image_validated_by_nsib = BOOT_CURR_IMG(state) == 1; + if (!image_validated_by_nsib) +#endif + { + FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL); + /* Check for all possible values is redundant in normal operation it + * is meant to prevent FI attack. + */ + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS) || + FIH_EQ(fih_rc, FIH_FAILURE) || + FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } } #else /* Even if we're not re-validating the primary slot, we could be booting @@ -2447,11 +2519,16 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } #endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */ +#ifdef PM_S1_ADDRESS + if (!image_validated_by_nsib) +#endif + { rc = boot_update_hw_rollback_protection(state); if (rc != 0) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } + } rc = boot_add_shared_data(state, BOOT_PRIMARY_SLOT); if (rc != 0) { diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 8999403c5..20caa2b5c 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -259,6 +259,18 @@ static int app_max_sectors(struct boot_loader_state *state) int boot_slots_compatible(struct boot_loader_state *state) { +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. In this case, image 1 primary points to the other + * B1 slot (ie S0 or S1), and image 0 primary points to the app. + * With this configuration, image 0 and image 1 share the secondary slot. + * Hence, the primary slot of image 1 will be *smaller* than image 1's + * secondary slot. This is not allowed in upstream mcuboot, so we need + * this patch to allow it. Also, all of these checks are redundant when + * partition manager is in use, and since we have the same sector size + * in all of our flash. + */ + return 1; +#else size_t num_sectors_pri; size_t num_sectors_sec; size_t sector_sz_pri = 0; @@ -306,6 +318,7 @@ boot_slots_compatible(struct boot_loader_state *state) } return 1; +#endif /* PM_S1_ADDRESS */ } #define BOOT_LOG_SWAP_STATE(area, state) \ diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index 24159d1db..08dffb186 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -141,6 +141,18 @@ boot_status_internal_off(const struct boot_status *bs, int elem_sz) int boot_slots_compatible(struct boot_loader_state *state) { +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. In this case, image 1 primary points to the other + * B1 slot (ie S0 or S1), and image 0 primary points to the app. + * With this configuration, image 0 and image 1 share the secondary slot. + * Hence, the primary slot of image 1 will be *smaller* than image 1's + * secondary slot. This is not allowed in upstream mcuboot, so we need + * this patch to allow it. Also, all of these checks are redundant when + * partition manager is in use, and since we have the same sector size + * in all of our flash. + */ + return 1; +#else size_t num_sectors_primary; size_t num_sectors_secondary; size_t sz0, sz1; @@ -228,6 +240,7 @@ boot_slots_compatible(struct boot_loader_state *state) #endif return 1; +#endif /* PM_S1_ADDRESS */ } #define BOOT_LOG_SWAP_STATE(area, state) \ diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 89d76e991..c3fe0bd74 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -295,6 +295,13 @@ if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "") endif() message("MCUBoot bootloader key file: ${KEY_FILE}") + set_property( + GLOBAL + PROPERTY + KEY_FILE + ${KEY_FILE} + ) + set(GENERATED_PUBKEY ${ZEPHYR_BINARY_DIR}/autogen-pubkey.c) add_custom_command( OUTPUT ${GENERATED_PUBKEY} diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 64e23ac6d..ffacd44b1 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -9,6 +9,8 @@ mainmenu "MCUboot configuration" comment "MCUboot-specific configuration options" +source "$(ZEPHYR_NRF_MODULE_DIR)/modules/mcuboot/boot/zephyr/Kconfig" + # Hidden option to mark a project as MCUboot config MCUBOOT default y diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 1952950b9..4eaf0309e 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -7,6 +7,52 @@ #ifndef __SYSFLASH_H__ #define __SYSFLASH_H__ +#if USE_PARTITION_MANAGER +#include +#include + +#ifndef CONFIG_SINGLE_APPLICATION_SLOT + +#if (MCUBOOT_IMAGE_NUMBER == 1) + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID + +#elif (MCUBOOT_IMAGE_NUMBER == 2) + +extern uint32_t _image_1_primary_slot_id[]; + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + (uint32_t)_image_1_primary_slot_id : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + 255 ) +#endif +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID + +#else /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID +/* NOTE: Scratch parition is not used by single image DFU but some of + * functions in common files reference it, so the definitions has been + * provided to allow compilation of common units. + */ +#define FLASH_AREA_IMAGE_SCRATCH 0 + +#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#else + +#include #include #include #include @@ -65,4 +111,6 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ +#endif /* USE_PARTITION_MANAGER */ + #endif /* __SYSFLASH_H__ */ diff --git a/boot/zephyr/include/target.h b/boot/zephyr/include/target.h index 9bbfd4b19..40287d515 100644 --- a/boot/zephyr/include/target.h +++ b/boot/zephyr/include/target.h @@ -8,6 +8,8 @@ #ifndef H_TARGETS_TARGET_ #define H_TARGETS_TARGET_ +#ifndef USE_PARTITION_MANAGER + #if defined(MCUBOOT_TARGET_CONFIG) /* * Target-specific definitions are permitted in legacy cases that @@ -45,4 +47,6 @@ #error "Target support is incomplete; cannot build mcuboot." #endif +#endif /* ifndef USE_PARTITION_MANAGER */ + #endif /* H_TARGETS_TARGET_ */ diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index ccabc2857..d3004d992 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -69,6 +69,10 @@ #endif /* CONFIG_SOC_FAMILY_ESPRESSIF_ESP32 */ +#ifdef CONFIG_FW_INFO +#include +#endif + #ifdef CONFIG_MCUBOOT_SERIAL #include "boot_serial/boot_serial.h" #include "serial_adapter/serial_adapter.h" @@ -129,6 +133,11 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); * !defined(ZEPHYR_LOG_MODE_MINIMAL) */ +#if USE_PARTITION_MANAGER && CONFIG_FPROTECT +#include +#include +#endif + BOOT_LOG_MODULE_REGISTER(mcuboot); void os_heap_init(void); @@ -187,6 +196,19 @@ static void do_boot(struct boot_rsp *rsp) /* Disable the USB to prevent it from firing interrupts */ usb_disable(); #endif + +#if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) + bool provided = fw_info_ext_api_provide(fw_info_find((uint32_t)vt), true); + +#ifdef PM_S0_ADDRESS + /* Only fail if the immutable bootloader is present. */ + if (!provided) { + BOOT_LOG_ERR("Failed to provide EXT_APIs\n"); + return; + } +#endif +#endif + #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ @@ -552,7 +574,30 @@ int main(void) mcuboot_status_change(MCUBOOT_STATUS_BOOTABLE_IMAGE_FOUND); +#if USE_PARTITION_MANAGER && CONFIG_FPROTECT + +#ifdef PM_S1_ADDRESS +/* MCUBoot is stored in either S0 or S1, protect both */ +#define PROTECT_SIZE (PM_MCUBOOT_PRIMARY_ADDRESS - PM_S0_ADDRESS) +#define PROTECT_ADDR PM_S0_ADDRESS +#else +/* There is only one instance of MCUBoot */ +#define PROTECT_SIZE (PM_MCUBOOT_PRIMARY_ADDRESS - PM_MCUBOOT_ADDRESS) +#define PROTECT_ADDR PM_MCUBOOT_ADDRESS +#endif + + rc = fprotect_area(PROTECT_ADDR, PROTECT_SIZE); + + if (rc != 0) { + BOOT_LOG_ERR("Protect mcuboot flash failed, cancel startup."); + while (1) + ; + } + +#endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ + ZEPHYR_BOOT_LOG_STOP(); + do_boot(&rsp); mcuboot_status_change(MCUBOOT_STATUS_BOOT_FAILED); diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml new file mode 100644 index 000000000..92c16d35f --- /dev/null +++ b/boot/zephyr/pm.yml @@ -0,0 +1,74 @@ +#include + +mcuboot: + size: CONFIG_PM_PARTITION_SIZE_MCUBOOT + placement: + before: [mcuboot_primary] + +mcuboot_primary_app: + # All images to be placed in MCUboot's slot 0 should be placed in this + # partition + span: [app] + +mcuboot_primary: + span: [mcuboot_pad, mcuboot_primary_app] + +# Partition for secondary slot is not created if building in single application +# slot configuration. +#if !defined(CONFIG_SINGLE_APPLICATION_SLOT) && !defined(CONFIG_BOOT_DIRECT_XIP) +mcuboot_secondary: + share_size: [mcuboot_primary] +#if defined(CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY) + region: external_flash + placement: + align: {start: 4} +#else + placement: + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} + align_next: CONFIG_FPROTECT_BLOCK_SIZE # Ensure that the next partition does not interfere with this image + after: mcuboot_primary +#endif /* CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY */ + +#endif /* !defined(CONFIG_SINGLE_APPLICATION_SLOT) && !defined(CONFIG_BOOT_DIRECT_XIP) */ + +#if CONFIG_BOOT_DIRECT_XIP + +# Direct XIP is enabled, reserve area for metadata (padding) and name the +# partition so that its clear that it is not the secondary slot, but the direct +# XIP alternative. + +mcuboot_secondary_pad: + share_size: mcuboot_pad + placement: + after: mcuboot_primary + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} + +mcuboot_secondary_app: + share_size: mcuboot_primary_app + placement: + after: mcuboot_secondary_pad + +mcuboot_secondary: + span: [mcuboot_secondary_pad, mcuboot_secondary_app] + +#endif /* CONFIG_BOOT_DIRECT_XIP */ + +#if CONFIG_BOOT_SWAP_USING_SCRATCH +mcuboot_scratch: + size: CONFIG_PM_PARTITION_SIZE_MCUBOOT_SCRATCH + placement: + after: app + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} +#endif /* CONFIG_BOOT_SWAP_USING_SCRATCH */ + +# Padding placed before image to boot. This reserves space for the MCUboot image header +# and it ensures that the boot image gets linked with the correct address offset in flash. +mcuboot_pad: + # MCUboot pad must be placed before the primary application partition. + # The primary application partition includes the secure firmware if present. + size: CONFIG_PM_PARTITION_SIZE_MCUBOOT_PAD + placement: + before: [mcuboot_primary_app] +#ifdef CONFIG_FPROTECT + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} +#endif diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 58cb2ae35..23b5f3b93 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -19,6 +19,7 @@ CONFIG_BOOT_BOOTSTRAP=n # CONFIG_TINYCRYPT_SHA256 is not set CONFIG_FLASH=y +CONFIG_FPROTECT=y ### Various Zephyr boards enable features that we don't want. # CONFIG_BT is not set diff --git a/ext/nrf/cc310_glue.h b/ext/nrf/cc310_glue.h index ed3ed5c00..22eb94911 100644 --- a/ext/nrf/cc310_glue.h +++ b/ext/nrf/cc310_glue.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include /* diff --git a/zephyr/module.yml b/zephyr/module.yml index 014a21956..9360dbf70 100644 --- a/zephyr/module.yml +++ b/zephyr/module.yml @@ -1,5 +1,6 @@ samples: - boot/zephyr build: - cmake: ./boot/bootutil/zephyr + cmake-ext: True + kconfig-ext: True sysbuild-cmake: boot/zephyr/sysbuild From 56934f9b475b51dbe20ef6e33621a57b7417c8ea Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Thu, 27 Aug 2020 14:29:31 +0200 Subject: [PATCH 178/238] [nrf noup] boot: nrf53-specific customizations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add network core bootloader implementation Enables network core updates of nrf53 using MCUBoot by identifying images through their start addresses. Also implements the control and transfer using the PCD module. - Add support for multi image DFU using partition manager. - Add check for netcore addr if NSIB is enabled so netcore updates works - boot: zephyr: move thingy53_nrf5340_cpuapp.conf downstream Moved the board configuration for Thingy:53 Application Core to the nRF Connect SDK MCUboot downstream repository. The configuration file contains references to the Kconfig modules that are only available in the nRF Connect SDK. The current configuration is set up to work in the nRF Connect SDK environment and cannot be used upstream. - pm: enable ram flash partition using common flag This patch makes mcuboot_primary_1 ram-flash partition selectable using CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH property. This is needed since CONFIG_NRF53_MULTI_IMAGE_UPDATE become not only configuration which requires that partition. - MCUBoot configures USB CDC by its own. There is no need for BOARD_SERIAL_BACKEND_CDC_ACM option to configure anything which is later overwritten anyway. Jira: NCSDK-18596 Signed-off-by: Andrzej Puzdrowski Signed-off-by: Emil Obalski Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Jamie McCrae Signed-off-by: Johann Fischer Signed-off-by: Kamil Piszczek Signed-off-by: Ole Sæther Signed-off-by: Sigvart Hovland Signed-off-by: Simon Iversen Signed-off-by: Torsten Rasmussen Signed-off-by: Trond Einar Snekvik Signed-off-by: Mateusz Kapala Signed-off-by: Dominik Ermel (cherry picked from commit 42e43d04e0b2327ac0722b070a3b2fa11f17fa34) --- boot/bootutil/src/loader.c | 96 ++++++++++++++----- .../boards/thingy53_nrf5340_cpuapp.conf | 74 +++++++++++++- boot/zephyr/include/sysflash/sysflash.h | 23 +++++ boot/zephyr/main.c | 7 ++ boot/zephyr/pm.yml | 13 +++ 5 files changed, 185 insertions(+), 28 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 9369445d1..5bdad6177 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,6 +49,10 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) +#include +#endif + #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" #endif @@ -1217,7 +1221,15 @@ boot_validated_swap_type(struct boot_loader_state *state, { int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); -#ifdef PM_S1_ADDRESS + bool upgrade_valid = false; + +#if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) + const struct flash_area *secondary_fa = + BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); + struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; + uint32_t vtable_addr = 0; + uint32_t *vtable = 0; + uint32_t reset_addr = 0; /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other * B1 slot S0 or S1) share the same secondary slot, we need to check * whether the update candidate in the secondary slot is intended for @@ -1225,34 +1237,36 @@ boot_validated_swap_type(struct boot_loader_state *state, * vector. Note that there are good reasons for not using img_num from * the swap info. */ - const struct flash_area *secondary_fa = - BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = - (struct image_header *)secondary_fa->fa_off; if (hdr->ih_magic == IMAGE_MAGIC) { - const struct flash_area *primary_fa; - uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - uint32_t *vtable = (uint32_t *)(vtable_addr); - uint32_t reset_addr = vtable[1]; - int rc = flash_area_open( - flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), - BOOT_PRIMARY_SLOT), - &primary_fa); - - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } - /* Get start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off || - reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for this image - */ - return BOOT_SWAP_TYPE_NONE; - } - } + vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + vtable = (uint32_t *)(vtable_addr); + reset_addr = vtable[1]; +#ifdef PM_S1_ADDRESS +#ifdef PM_CPUNET_B0N_ADDRESS + if(reset_addr < PM_CPUNET_B0N_ADDRESS) #endif + { + const struct flash_area *primary_fa; + int rc = flash_area_open(flash_area_id_from_multi_image_slot( + BOOT_CURR_IMG(state), + BOOT_PRIMARY_SLOT), + &primary_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + /* Get start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off || + reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for this image + */ + return BOOT_SWAP_TYPE_NONE; + } + } +#endif /* PM_S1_ADDRESS */ + } +#endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -1266,7 +1280,37 @@ boot_validated_swap_type(struct boot_loader_state *state, } else { swap_type = BOOT_SWAP_TYPE_FAIL; } + } else { + upgrade_valid = true; + } + +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) + /* If the update is valid, and it targets the network core: perform the + * update and indicate to the caller of this function that no update is + * available + */ + if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { + uint32_t fw_size = hdr->ih_img_size; + + BOOT_LOG_INF("Starting network core update"); + int rc = pcd_network_core_update(vtable, fw_size); + + if (rc != 0) { + swap_type = BOOT_SWAP_TYPE_FAIL; + } else { + BOOT_LOG_INF("Done updating network core"); +#if defined(MCUBOOT_SWAP_USING_SCRATCH) || defined(MCUBOOT_SWAP_USING_MOVE) + /* swap_erase_trailer_sectors is undefined if upgrade only + * method is used. There is no need to erase sectors, because + * the image cannot be reverted. + */ + rc = swap_erase_trailer_sectors(state, + secondary_fa); +#endif + swap_type = BOOT_SWAP_TYPE_NONE; + } } +#endif /* CONFIG_SOC_NRF5340_CPUAPP */ } return swap_type; diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf index f2e42fd64..7d3bc0bec 100644 --- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf @@ -1,3 +1,73 @@ -CONFIG_NORDIC_QSPI_NOR=n -CONFIG_SPI=n +CONFIG_SIZE_OPTIMIZATIONS=y + +CONFIG_SYSTEM_CLOCK_NO_WAIT=y +CONFIG_PM=n + +CONFIG_MAIN_STACK_SIZE=10240 +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +CONFIG_BOOT_MAX_IMG_SECTORS=2048 +CONFIG_BOOT_SIGNATURE_TYPE_RSA=y + +# Flash +CONFIG_FLASH=y +CONFIG_BOOT_ERASE_PROGRESSIVELY=y +CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y +CONFIG_FPROTECT=y + +# Serial +CONFIG_SERIAL=y +CONFIG_UART_LINE_CTRL=y + +# MCUBoot serial +CONFIG_GPIO=y +CONFIG_MCUBOOT_SERIAL=y +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +CONFIG_BOOT_SERIAL_CDC_ACM=y + +# Required by QSPI +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# Required by USB and QSPI CONFIG_MULTITHREADING=y + +# USB +CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n +CONFIG_USB_DEVICE_REMOTE_WAKEUP=n +CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor ASA" +CONFIG_USB_DEVICE_PRODUCT="Bootloader Thingy:53" +CONFIG_USB_DEVICE_VID=0x1915 +CONFIG_USB_DEVICE_PID=0x5300 +CONFIG_USB_CDC_ACM=y + +# Decrease memory footprint +CONFIG_CBPRINTF_NANO=y +CONFIG_TIMESLICING=n +CONFIG_BOOT_BANNER=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_LOG=n +CONFIG_ERRNO=n +CONFIG_PRINTK=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_SPI=n +CONFIG_I2C=n +CONFIG_UART_NRFX=n + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 +CONFIG_BOOT_UPGRADE_ONLY=y +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +# Enable custom command to erase settings partition. +CONFIG_ENABLE_MGMT_PERUSER=y +CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 4eaf0309e..b98e48bce 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -20,6 +20,11 @@ #elif (MCUBOOT_IMAGE_NUMBER == 2) +/* If B0 is present then two bootloaders are present, and we must use + * a single secondary slot for both primary slots. + */ +#ifdef PM_B0_ADDRESS + extern uint32_t _image_1_primary_slot_id[]; #define FLASH_AREA_IMAGE_PRIMARY(x) \ @@ -35,6 +40,24 @@ extern uint32_t _image_1_primary_slot_id[]; (x == 1) ? \ PM_MCUBOOT_SECONDARY_ID: \ 255 ) +#else + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) + +#endif /* PM_B0_ADDRESS */ + #endif #define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index d3004d992..7148e14fe 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -91,6 +91,10 @@ const struct boot_uart_funcs boot_funcs = { #include #endif +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) +#include +#endif + /* CONFIG_LOG_MINIMAL is the legacy Kconfig property, * replaced by CONFIG_LOG_MODE_MINIMAL. */ @@ -594,6 +598,9 @@ int main(void) ; } +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) && defined(CONFIG_PCD_APP) + pcd_lock_ram(); +#endif #endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ ZEPHYR_BOOT_LOG_STOP(); diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml index 92c16d35f..eabe3d08e 100644 --- a/boot/zephyr/pm.yml +++ b/boot/zephyr/pm.yml @@ -72,3 +72,16 @@ mcuboot_pad: #ifdef CONFIG_FPROTECT align: {start: CONFIG_FPROTECT_BLOCK_SIZE} #endif + +#if (CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH) +mcuboot_primary_1: + region: ram_flash + size: CONFIG_NRF53_RAM_FLASH_SIZE +#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ + +#if (CONFIG_NRF53_MULTI_IMAGE_UPDATE) +mcuboot_secondary_1: + region: external_flash + size: CONFIG_NRF53_RAM_FLASH_SIZE + +#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ From 50c5cdb7ef0dcbe29fc70ebe047c682f7b5b01c3 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 27 Feb 2020 12:48:56 +0100 Subject: [PATCH 179/238] [nrf noup] zephyr: clean peripherals state before boot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do some cleanup of nRF peripherals. This is necessary since Zephyr doesn't have any driver deinitialization functionality, and we'd like to leave peripherals in a more predictable state before booting the Zephyr image. This should be re-worked when the zephyr driver model allows us to deinitialize devices cleanly before jumping to the chain-loaded image. Signed-off-by: Andrzej Puzdrowski Signed-off-by: Robert Lubos Signed-off-by: Torsten Rasmussen Signed-off-by: Øyvind Rønningstad Signed-off-by: Martí Bolívar Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Johann Fischer Signed-off-by: Trond Einar Snekvik Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 3b2a5baea3a31a399508f338ccf2e0696939451a) --- boot/zephyr/CMakeLists.txt | 6 +++ boot/zephyr/include/nrf_cleanup.h | 19 +++++++ boot/zephyr/main.c | 8 ++- boot/zephyr/nrf_cleanup.c | 83 +++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 boot/zephyr/include/nrf_cleanup.h create mode 100644 boot/zephyr/nrf_cleanup.c diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index c3fe0bd74..b60b0c95d 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -574,3 +574,9 @@ if(SYSBUILD) set(mcuboot_image_footer_size ${required_size} CACHE INTERNAL "Estimated MCUboot image trailer size" FORCE) set(mcuboot_image_upgrade_footer_size ${required_upgrade_size} CACHE INTERNAL "Estimated MCUboot update image trailer size" FORCE) endif() + +if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL) +zephyr_library_sources( + ${BOOT_DIR}/zephyr/nrf_cleanup.c +) +endif() diff --git a/boot/zephyr/include/nrf_cleanup.h b/boot/zephyr/include/nrf_cleanup.h new file mode 100644 index 000000000..6b04cedfe --- /dev/null +++ b/boot/zephyr/include/nrf_cleanup.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef H_NRF_CLEANUP_ +#define H_NRF_CLEANUP_ + +/** + * Perform cleanup on some peripheral resources used by MCUBoot prior chainload + * the application. + * + * This function disables all RTC instances and UARTE instances. + * It Disables their interrupts signals as well. + */ +void nrf_cleanup_peripheral(void); + +#endif diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 7148e14fe..3603cc579 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -142,6 +142,10 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); #include #endif +#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL +#include +#endif + BOOT_LOG_MODULE_REGISTER(mcuboot); void os_heap_init(void); @@ -212,7 +216,9 @@ static void do_boot(struct boot_rsp *rsp) } #endif #endif - +#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL + nrf_cleanup_peripheral(); +#endif #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c new file mode 100644 index 000000000..5bab26b24 --- /dev/null +++ b/boot/zephyr/nrf_cleanup.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#if defined(NRF_UARTE0) || defined(NRF_UARTE1) + #include +#endif +#if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) + #include +#endif +#if defined(NRF_PPI) + #include +#endif +#if defined(NRF_DPPIC) + #include +#endif + +#include + +#define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) +#define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ + NRF_UARTE_SUBSCRIBE_CONF_OFFS) + +#define NRF_UARTE_PUBLISH_CONF_OFFS offsetof(NRF_UARTE_Type, PUBLISH_CTS) +#define NRF_UARTE_PUBLISH_CONF_SIZE (offsetof(NRF_UARTE_Type, SHORTS) -\ + NRF_UARTE_PUBLISH_CONF_OFFS) + +#if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) +static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) +{ + nrf_rtc_task_trigger(rtc_reg, NRF_RTC_TASK_STOP); + nrf_rtc_event_disable(rtc_reg, 0xFFFFFFFF); + nrf_rtc_int_disable(rtc_reg, 0xFFFFFFFF); +} +#endif + +static void nrf_cleanup_clock(void) +{ + nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); +} + +void nrf_cleanup_peripheral(void) +{ +#if defined(NRF_RTC0) + nrf_cleanup_rtc(NRF_RTC0); +#endif +#if defined(NRF_RTC1) + nrf_cleanup_rtc(NRF_RTC1); +#endif +#if defined(NRF_RTC2) + nrf_cleanup_rtc(NRF_RTC2); +#endif +#if defined(NRF_UARTE0) + nrf_uarte_disable(NRF_UARTE0); + nrf_uarte_int_disable(NRF_UARTE0, 0xFFFFFFFF); +#if defined(NRF_DPPIC) + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); +#endif +#endif +#if defined(NRF_UARTE1) + nrf_uarte_disable(NRF_UARTE1); + nrf_uarte_int_disable(NRF_UARTE1, 0xFFFFFFFF); +#if defined(NRF_DPPIC) + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); +#endif +#endif +#if defined(NRF_PPI) + nrf_ppi_channels_disable_all(NRF_PPI); +#endif +#if defined(NRF_DPPIC) + nrf_dppi_channels_disable_all(NRF_DPPIC); +#endif + nrf_cleanup_clock(); +} From d04dd27a2465abe302776a0fab654682a5f0d223 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Fri, 6 Jan 2023 12:24:48 +0100 Subject: [PATCH 180/238] [nrf noup] zephyr: Clean up non-secure RAM if enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To ensure that MCUBoot does not leak keys or other material through memory to non-secure side we clear the memory before jumping to the next image. Signed-off-by: Sigvart Hovland Signed-off-by: Dominik Ermel Signed-off-by: Ole Sæther (cherry picked from commit 047d463df16e048e4f85283bf57b7228c62ff17b) --- boot/zephyr/CMakeLists.txt | 2 +- boot/zephyr/include/nrf_cleanup.h | 5 +++++ boot/zephyr/main.c | 5 ++++- boot/zephyr/nrf_cleanup.c | 13 +++++++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index b60b0c95d..fde155833 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -575,7 +575,7 @@ if(SYSBUILD) set(mcuboot_image_upgrade_footer_size ${required_upgrade_size} CACHE INTERNAL "Estimated MCUboot update image trailer size" FORCE) endif() -if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL) +if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL OR CONFIG_MCUBOOT_CLEANUP_NONSECURE_RAM) zephyr_library_sources( ${BOOT_DIR}/zephyr/nrf_cleanup.c ) diff --git a/boot/zephyr/include/nrf_cleanup.h b/boot/zephyr/include/nrf_cleanup.h index 6b04cedfe..9e87e13f5 100644 --- a/boot/zephyr/include/nrf_cleanup.h +++ b/boot/zephyr/include/nrf_cleanup.h @@ -16,4 +16,9 @@ */ void nrf_cleanup_peripheral(void); +/** + * Perform cleanup of non-secure RAM that may have been used by MCUBoot. + */ +void nrf_cleanup_ns_ram(void); + #endif diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 3603cc579..7b331a792 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -142,7 +142,7 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); #include #endif -#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL +#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL || CONFIG_MCUBOOT_NRF_CLEANUP_NONSECURE_RAM #include #endif @@ -219,6 +219,9 @@ static void do_boot(struct boot_rsp *rsp) #if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL nrf_cleanup_peripheral(); #endif +#if CONFIG_MCUBOOT_NRF_CLEANUP_NONSECURE_RAM && defined(PM_SRAM_NONSECURE_NAME) + nrf_cleanup_ns_ram(); +#endif #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 5bab26b24..2165159ea 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -20,6 +20,10 @@ #include +#if USE_PARTITION_MANAGER +#include +#endif + #define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) #define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ NRF_UARTE_SUBSCRIBE_CONF_OFFS) @@ -81,3 +85,12 @@ void nrf_cleanup_peripheral(void) #endif nrf_cleanup_clock(); } + +#if USE_PARTITION_MANAGER \ + && defined(CONFIG_ARM_TRUSTZONE_M) \ + && defined(PM_SRAM_NONSECURE_NAME) +void nrf_cleanup_ns_ram(void) +{ + memset((void *) PM_SRAM_NONSECURE_ADDRESS, 0, PM_SRAM_NONSECURE_SIZE); +} +#endif From a3a50e720af5c70dbc6ca52331b9e8e951fa43d7 Mon Sep 17 00:00:00 2001 From: Christian Taedcke Date: Thu, 10 Feb 2022 15:37:49 +0100 Subject: [PATCH 181/238] [nrf noup] loader: Fix reading reset addr to support ext flash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When mcuboot_secondary is on external flash, the image header cannot dircetly be accessed via secondary_fa->fa_off. Instead the provided function boot_img_hdr() is used now. Additionally a similar issue is present when trying to read the address of the reset handler. For this flash_area_read() is used now. With this patch is possible to have the update partiton mcuboot_secondary on external flash and update a updatable bootloader (mcuboot) in s0 and/or s1. Signed-off-by: Christian Taedcke Signed-off-by: Ole Sæther Signed-off-by: Sigvart Hovland Signed-off-by: Dominik Ermel (cherry picked from commit 2dac63a3ecd987c056351e09bdb240c3af37ecfe) --- boot/bootutil/src/loader.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 5bdad6177..eda1fc71f 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1226,10 +1226,9 @@ boot_validated_swap_type(struct boot_loader_state *state, #if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) const struct flash_area *secondary_fa = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; - uint32_t vtable_addr = 0; - uint32_t *vtable = 0; + struct image_header *hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); uint32_t reset_addr = 0; + int rc = 0; /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other * B1 slot S0 or S1) share the same secondary slot, we need to check * whether the update candidate in the secondary slot is intended for @@ -1239,16 +1238,19 @@ boot_validated_swap_type(struct boot_loader_state *state, */ if (hdr->ih_magic == IMAGE_MAGIC) { - vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - vtable = (uint32_t *)(vtable_addr); - reset_addr = vtable[1]; + rc = flash_area_read(secondary_fa, hdr->ih_hdr_size + + sizeof(uint32_t), &reset_addr, + sizeof(reset_addr)); + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS if(reset_addr < PM_CPUNET_B0N_ADDRESS) #endif { const struct flash_area *primary_fa; - int rc = flash_area_open(flash_area_id_from_multi_image_slot( + rc = flash_area_open(flash_area_id_from_multi_image_slot( BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT), &primary_fa); @@ -1284,16 +1286,19 @@ boot_validated_swap_type(struct boot_loader_state *state, upgrade_valid = true; } -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) \ + && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) /* If the update is valid, and it targets the network core: perform the * update and indicate to the caller of this function that no update is * available */ if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { + struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; + uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr); uint32_t fw_size = hdr->ih_img_size; - BOOT_LOG_INF("Starting network core update"); - int rc = pcd_network_core_update(vtable, fw_size); + rc = pcd_network_core_update(net_core_fw_addr, fw_size); if (rc != 0) { swap_type = BOOT_SWAP_TYPE_FAIL; From 76d0d9a6b501d4cd51268c0dded8f76152c0452d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 11 Jul 2023 08:42:49 +0100 Subject: [PATCH 182/238] [nrf noup] zephyr: Fix path variables Fixes path variables to use the proper Zephyr module variables Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit c28fa1d8c6d4d5a73b08394f0e96f7cb2f3e3d8f) --- boot/zephyr/CMakeLists.txt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index fde155833..a288410bf 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -27,21 +27,20 @@ assert_exists(FIAT_DIR) # Path to mbed-tls' asn1 parser library. set(MBEDTLS_ASN1_DIR "${MCUBOOT_DIR}/ext/mbedtls-asn1") assert_exists(MBEDTLS_ASN1_DIR) -set(NRF_DIR "${MCUBOOT_DIR}/ext/nrf") +set(MCUBOOT_NRF_EXT_DIR "${MCUBOOT_DIR}/ext/nrf") if(CONFIG_BOOT_USE_NRF_CC310_BL) -set(NRFXLIB_DIR ${ZEPHYR_BASE}/../nrfxlib) -if(NOT EXISTS ${NRFXLIB_DIR}) - message(FATAL_ERROR " + if(NOT EXISTS ${ZEPHYR_NRFXLIB_MODULE_DIR}) + message(FATAL_ERROR " ------------------------------------------------------------------------ - No such file or directory: ${NRFXLIB_DIR} + No such file or directory: ${ZEPHYR_NRFXLIB_MODULE_DIR} The current configuration enables nRF CC310 crypto accelerator hardware with the `CONFIG_BOOT_USE_NRF_CC310_BL` option. Please follow `ext/nrf/README.md` guide to fix your setup or use tinycrypt instead of the HW accelerator. To use the tinycrypt set `CONFIG_BOOT_ECDSA_TINYCRYPT` to y. ------------------------------------------------------------------------") -endif() + endif() endif() zephyr_library_include_directories( @@ -169,8 +168,8 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) ${TINYCRYPT_DIR}/source/utils.c ) elseif(CONFIG_BOOT_USE_NRF_CC310_BL) - zephyr_library_sources(${NRF_DIR}/cc310_glue.c) - zephyr_library_include_directories(${NRF_DIR}) + zephyr_library_sources(${MCUBOOT_NRF_EXT_DIR}/cc310_glue.c) + zephyr_library_include_directories(${MCUBOOT_NRF_EXT_DIR}) zephyr_link_libraries(nrfxlib_crypto) endif() From 5a8e708be4ac381fccc74b45e2ce2fa4d2963723 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 22 Sep 2023 21:31:08 +0000 Subject: [PATCH 183/238] [nrf noup] loader: Do not check reset vector for XIP image The XIP image, 2, does not have reset vector. Signed-off-by: Dominik Ermel (cherry picked from commit d798de3f27589d640a750d98aca4e91affbf927b) --- boot/bootutil/src/loader.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index eda1fc71f..30eca76e8 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1109,6 +1109,16 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * overwriting an application written to the incorrect slot. * This feature is only supported by ARM platforms. */ +#if MCUBOOT_IMAGE_NUMBER >= 3 + /* Currently the MCUboot can be configured for up to 3 image, where image number 2 is + * designated for XIP, where it is the second part of image stored in slots of image + * 0. This part of image is not bootable, as the XIP setup is done by the app in + * image 0 slot, and it does not carry the reset vector. + */ + if (area_id == FLASH_AREA_IMAGE_SECONDARY(2)) { + goto out; + } +#endif if (area_id == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) { const struct flash_area *pri_fa = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); struct image_header *secondary_hdr = boot_img_hdr(state, slot); From 9599724eace330fe16564ce6cc85e6ab65e6f2b0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 18 Sep 2023 13:47:00 +0100 Subject: [PATCH 184/238] [nrf noup] zephyr: Add RAM flash configuration to cache for sysbuild Puts the flash simulation configurtion into cache variables that can be used by other applications and CMake code to know specifics on the simulated flash details Signed-off-by: Jamie McCrae (cherry picked from commit af27205c904fa5eee91eb3a9cec3a1eea939b4aa) --- boot/zephyr/CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index a288410bf..1d3009b22 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -579,3 +579,14 @@ zephyr_library_sources( ${BOOT_DIR}/zephyr/nrf_cleanup.c ) endif() + +if(SYSBUILD AND CONFIG_PCD_APP) + # Sysbuild requires details of the RAM flash device are stored to the cache of MCUboot so + # that they can be read when running partition manager + dt_nodelabel(ram_flash_dev NODELABEL flash_sim0) + dt_reg_addr(ram_flash_addr PATH ${ram_flash_dev}) + dt_reg_size(ram_flash_size PATH ${ram_flash_dev}) + + set(RAM_FLASH_ADDR "${ram_flash_addr}" CACHE STRING "" FORCE) + set(RAM_FLASH_SIZE "${ram_flash_size}" CACHE STRING "" FORCE) +endif() From 5b374005c2080103017c6f2f1df20cb7a158d5ef Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Tue, 17 Oct 2023 11:28:09 +0200 Subject: [PATCH 185/238] [nrf noup] zephyr: Boot even if EXT_ABI is not provided This removes the `return;` to ensure that the application is booted even if EXT_ABI is not provided to the application because it does not include `FW_INFO`. Added a bit more description to the error messages when FW_INFO is not found and EXT_ABI is not able to be provided to the next image. Ref. NCSDK-24132 Signed-off-by: Sigvart Hovland (cherry picked from commit 41cc274e70465192a973b28ca9463c22e3ae9e82) --- boot/zephyr/main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 7b331a792..4c3f47ee5 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -206,13 +206,16 @@ static void do_boot(struct boot_rsp *rsp) #endif #if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - bool provided = fw_info_ext_api_provide(fw_info_find((uint32_t)vt), true); + const struct fw_info *firmware_info = fw_info_find((uint32_t) vt); + bool provided = fw_info_ext_api_provide(firmware_info, true); #ifdef PM_S0_ADDRESS /* Only fail if the immutable bootloader is present. */ if (!provided) { - BOOT_LOG_ERR("Failed to provide EXT_APIs\n"); - return; + if (firmware_info == NULL) { + BOOT_LOG_WRN("Unable to find firmware info structure in %p", vt); + } + BOOT_LOG_ERR("Failed to provide EXT_APIs to %p", vt); } #endif #endif From 20113950310c518f83e4c15f72bc6c4168e2fb8a Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Wed, 27 Sep 2023 15:18:04 +0200 Subject: [PATCH 186/238] =?UTF-8?q?[nrf=20noup]=C2=A0loader:=20Add=20firmw?= =?UTF-8?q?are=20version=20check=20downgrade=20prevention?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For nRF53, the only existing version number metadata is stored in the `firmware_info` structure in the network core. This utilizes PCD to read out the version number and compares it against the version number found in the secondary slot for the network core. Ref. NCSDK-21379 Signed-off-by: Sigvart Hovland (cherry picked from commit 8e91ec1b9ea30ba0ca201bf8fb8cdf173f1188e7) --- boot/bootutil/src/loader.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 30eca76e8..32782fcf7 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -51,6 +51,10 @@ #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) #include +#ifdef CONFIG_PCD_READ_NETCORE_APP_VERSION +#include +int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); +#endif #endif #ifdef MCUBOOT_ENC_IMAGES @@ -1065,9 +1069,21 @@ boot_validate_slot(struct boot_loader_state *state, int slot, #if defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION) if (slot != BOOT_PRIMARY_SLOT) { /* Check if version of secondary slot is sufficient */ - rc = boot_version_cmp( - &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, - &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); + +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) \ + && defined(CONFIG_PCD_APP) && defined(CONFIG_PCD_READ_NETCORE_APP_VERSION) + if (BOOT_CURR_IMG(state) == 1) { + rc = pcd_version_cmp_net(fap, boot_img_hdr(state, BOOT_SECONDARY_SLOT)); + } else { + rc = boot_version_cmp( + &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, + &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); + } +#else + rc = boot_version_cmp( + &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, + &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); +#endif if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) { BOOT_LOG_ERR("insufficient version in secondary slot"); flash_area_erase(fap, 0, flash_area_get_size(fap)); From 39bbebf4de3fb0ec6ddb60176814500a8d93baea Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Mon, 9 Oct 2023 09:55:57 +0200 Subject: [PATCH 187/238] [nrf noup] boards: thingy53: disable GPIO ISR support Change disables GPIO interrupt support in Zephyr GPIO driver, which is not obligatory for MCUboot. This is needed to reduce memory footprint. Signed-off-by: Nikodem Kastelik (cherry picked from commit 86af2de75205ec5f2c846a2393934360de22fde4) --- boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf index 7d3bc0bec..e10656678 100644 --- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf @@ -21,6 +21,7 @@ CONFIG_UART_LINE_CTRL=y # MCUBoot serial CONFIG_GPIO=y +CONFIG_GPIO_NRFX_INTERRUPT=n CONFIG_MCUBOOT_SERIAL=y CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y CONFIG_BOOT_SERIAL_CDC_ACM=y From 6f3eb6888f2351799e6896c854c7f977ef1b2fd3 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 11 Apr 2024 17:26:50 +0200 Subject: [PATCH 188/238] [nrf noup] boot/zephyr/boards: nRF54l15pdk ext flash cfg Added configuration which allows to build MCUboot for nrf54l15pdk_nrf54l15_cpuapp with external flash used for the secondary slot. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 78bc87c46a9501cacd57003271968a554d30e0ee) --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf | 8 ++++++++ .../nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 10 ++++++++++ 2 files changed, 18 insertions(+) create mode 100644 boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf create mode 100644 boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf new file mode 100644 index 000000000..841922dbd --- /dev/null +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf @@ -0,0 +1,8 @@ +CONFIG_MULTITHREADING=y +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_FLASH=y +CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 +CONFIG_MAIN_STACK_SIZE=20480 +CONFIG_BOOT_MAX_IMG_SECTORS=512 +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay new file mode 100644 index 000000000..2341ffd26 --- /dev/null +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -0,0 +1,10 @@ +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; + + +&mx25r64 { + status = "okay"; +}; From 6f9c198e21bb817dc4cb92e2a82b815be2d71d0d Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Tue, 30 Mar 2021 22:45:17 +0200 Subject: [PATCH 189/238] [nrf noup] loader: work-around for multi-image builds Seems multi-image dependencies are not supported for multi-image in NCS yet. This is a workaround which reverts some lines to restore previous MCUboot behavior, so that Immutable bootloader + MCUBoot type builds will work. Ref. NCSDK-8681 Signed-off-by: Sigvart Hovland (cherry picked from commit 4ce3844d5fb9a1b0f90b2f95461f23cdba3e9080) --- boot/bootutil/src/loader.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 32782fcf7..c6d098169 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -414,7 +414,7 @@ boot_verify_dependencies(struct boot_loader_state *state) if (rc == 0) { /* All dependencies've been satisfied, continue with next image. */ BOOT_CURR_IMG(state)++; - } else { + } else if (rc == BOOT_EBADIMAGE) { /* Cannot upgrade due to non-met dependencies, so disable all * image upgrades. */ @@ -423,7 +423,10 @@ boot_verify_dependencies(struct boot_loader_state *state) BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE; } break; - } + } else { + /* Other error happened, images are inconsistent */ + return rc; + } } return rc; } @@ -1821,7 +1824,6 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) } #endif - /** * Performs a clean (not aborted) image update. * From dced8660b5dc8590d32d78950a70907e026dc5c5 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 31 Aug 2023 08:58:31 +0100 Subject: [PATCH 190/238] [nrf noup] loader: Fix missing PCD define check Fixes a missing PCD define check, an image might have the network core partition layout set but if PCD support is not enabled then it should not assume that PCD support is part of mcuboot. Signed-off-by: Jamie McCrae (cherry picked from commit 150a1d473c46e31be583e568348f1303be90cfad) --- boot/bootutil/src/loader.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index c6d098169..9d74a94ce 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1316,7 +1316,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) \ - && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) && defined(CONFIG_PCD_APP) /* If the update is valid, and it targets the network core: perform the * update and indicate to the caller of this function that no update is * available @@ -1344,7 +1344,8 @@ boot_validated_swap_type(struct boot_loader_state *state, swap_type = BOOT_SWAP_TYPE_NONE; } } -#endif /* CONFIG_SOC_NRF5340_CPUAPP */ +#endif /* CONFIG_SOC_NRF5340_CPUAPP && PM_CPUNET_B0N_ADDRESS && + !CONFIG_NRF53_MULTI_IMAGE_UPDATE && CONFIG_PCD_APP */ } return swap_type; From a7cea4e88eae4925daf7b0ca7e74bb8d49f37858 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Wed, 31 May 2023 14:41:13 +0200 Subject: [PATCH 191/238] [nrf noup] boot: Add support for NSIB and multi-image This adds support for using both NSIB and the multi-image configuration in MCUboot. Before this was not possible due to upgradable bootloader support through NSIB was using the `UPDATEABLE_IMAGE_NUMBER` configuration to update the updateable bootloader. In this commit we change from using `FLASH_AREA_IMAGE_PRIMARY` to get the flash area ID to using the bootloader state where we set the flash area ID of the free updatable bootloader slot if the image is intended for this slot. Ref. NCSDK-19223 Ref. NCSDK-23305 Signed-off-by: Sigvart Hovland (cherry picked from commit 3ec508400ba3a7d3e5e5bc73e7d4efa78b3375eb) --- boot/bootutil/src/loader.c | 44 +++++++++++++++++++------ boot/zephyr/include/sysflash/sysflash.h | 19 +++++++++-- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 9d74a94ce..c43b64d06 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1160,6 +1160,11 @@ boot_validate_slot(struct boot_loader_state *state, int slot, if (BOOT_CURR_IMG(state) == 1) { min_addr = PM_CPUNET_APP_ADDRESS; max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; +#ifdef PM_S1_ADDRESS + } else if (BOOT_CURR_IMG(state) == 0) { + min_addr = PM_S0_ADDRESS; + max_addr = pri_fa->fa_off + pri_fa->fa_size; +#endif } else #endif { @@ -1280,18 +1285,37 @@ boot_validated_swap_type(struct boot_loader_state *state, { const struct flash_area *primary_fa; rc = flash_area_open(flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), - BOOT_PRIMARY_SLOT), - &primary_fa); - + BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT), + &primary_fa); if (rc != 0) { return BOOT_SWAP_TYPE_FAIL; } - /* Get start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off || - reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for this image - */ + + /* Check start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off) { +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + const struct flash_area *nsib_fa; + + /* NSIB upgrade slot */ + rc = flash_area_open((uint32_t)_image_1_primary_slot_id, + &nsib_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + + /* Image is placed before Primary and within the NSIB slot */ + if (reset_addr > nsib_fa->fa_off + && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { + /* Set primary to be NSIB upgrade slot */ + BOOT_IMG_AREA(state, 0) = nsib_fa; + } +#else + return BOOT_SWAP_TYPE_NONE; +#endif + + } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for any */ return BOOT_SWAP_TYPE_NONE; } } @@ -1567,7 +1591,7 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) BOOT_LOG_INF("Image %d upgrade secondary slot -> primary slot", image_index); BOOT_LOG_INF("Erasing the primary slot"); - rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), + rc = flash_area_open(flash_area_get_id(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)), &fap_primary_slot); assert (rc == 0); diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index b98e48bce..8b47a32b5 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -23,9 +23,24 @@ /* If B0 is present then two bootloaders are present, and we must use * a single secondary slot for both primary slots. */ -#ifdef PM_B0_ADDRESS - +#if defined(PM_B0_ADDRESS) extern uint32_t _image_1_primary_slot_id[]; +#endif +#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) +#elif defined(PM_B0_ADDRESS) #define FLASH_AREA_IMAGE_PRIMARY(x) \ ((x == 0) ? \ From fbe4075f6d08dc5e5dab52fa0d4b4bf512b1981e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 10 Aug 2023 17:32:48 +0000 Subject: [PATCH 192/238] [nrf noup] sysflash: Move partition manager definitions to pm_sysflash.h Making sysflash.h and pm_sysflash.h more readable. Signed-off-by: Dominik Ermel (cherry picked from commit 51b7a3f1839d909cf0eeabdee72d3a92ff4a304a) --- boot/zephyr/include/sysflash/pm_sysflash.h | 92 ++++++++++++++++++++++ boot/zephyr/include/sysflash/sysflash.h | 90 ++------------------- 2 files changed, 97 insertions(+), 85 deletions(-) create mode 100644 boot/zephyr/include/sysflash/pm_sysflash.h diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h new file mode 100644 index 000000000..377291e8b --- /dev/null +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef __PM_SYSFLASH_H__ +#define __PM_SYSFLASH_H__ +/* Blocking the __SYSFLASH_H__ */ +#define __SYSFLASH_H__ + +#include +#include + +#ifndef CONFIG_SINGLE_APPLICATION_SLOT + +#if (MCUBOOT_IMAGE_NUMBER == 1) + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID + +#elif (MCUBOOT_IMAGE_NUMBER == 2) + +/* If B0 is present then two bootloaders are present, and we must use + * a single secondary slot for both primary slots. + */ +#if defined(PM_B0_ADDRESS) +extern uint32_t _image_1_primary_slot_id[]; +#endif +#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) +#elif defined(PM_B0_ADDRESS) + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + (uint32_t)_image_1_primary_slot_id : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + 255 ) +#else + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) + +#endif /* PM_B0_ADDRESS */ + +#endif +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID + +#else /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID +/* NOTE: Scratch parition is not used by single image DFU but some of + * functions in common files reference it, so the definitions has been + * provided to allow compilation of common units. + */ +#define FLASH_AREA_IMAGE_SCRATCH 0 + +#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#endif /* __PM_SYSFLASH_H__ */ diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 8b47a32b5..f231c3d02 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -4,93 +4,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __SYSFLASH_H__ -#define __SYSFLASH_H__ - #if USE_PARTITION_MANAGER -#include -#include - -#ifndef CONFIG_SINGLE_APPLICATION_SLOT - -#if (MCUBOOT_IMAGE_NUMBER == 1) - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID - -#elif (MCUBOOT_IMAGE_NUMBER == 2) - -/* If B0 is present then two bootloaders are present, and we must use - * a single secondary slot for both primary slots. - */ -#if defined(PM_B0_ADDRESS) -extern uint32_t _image_1_primary_slot_id[]; -#endif -#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) -#elif defined(PM_B0_ADDRESS) - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - (uint32_t)_image_1_primary_slot_id : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - 255 ) -#else - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) - -#endif /* PM_B0_ADDRESS */ - +/* Blocking the rest of the file */ +#define __SYSFLASH_H__ +#include #endif -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID - -#else /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID -/* NOTE: Scratch parition is not used by single image DFU but some of - * functions in common files reference it, so the definitions has been - * provided to allow compilation of common units. - */ -#define FLASH_AREA_IMAGE_SCRATCH 0 -#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#else +#ifndef __SYSFLASH_H__ +#define __SYSFLASH_H__ -#include #include #include #include @@ -149,6 +71,4 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ -#endif /* USE_PARTITION_MANAGER */ - #endif /* __SYSFLASH_H__ */ From e80e79387a312046f24e9bc946c9fa5822687f0e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 11 Aug 2023 12:29:13 +0000 Subject: [PATCH 193/238] [nrf noup] sysflash: Add support for three images The commit modifies pm_sysflash.h to add support for three application images. Ref. NCSDK-19223 Signed-off-by: Dominik Ermel Signed-off-by: Sigvart Hovland (cherry picked from commit 9c673510b53a4b2c531d565ed98201d4bbbbfb07) --- boot/zephyr/include/sysflash/pm_sysflash.h | 82 ++++++++++++---------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h index 377291e8b..db60ddd03 100644 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -11,37 +11,19 @@ #include #include +#include #ifndef CONFIG_SINGLE_APPLICATION_SLOT -#if (MCUBOOT_IMAGE_NUMBER == 1) - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID - -#elif (MCUBOOT_IMAGE_NUMBER == 2) - +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) /* If B0 is present then two bootloaders are present, and we must use * a single secondary slot for both primary slots. */ -#if defined(PM_B0_ADDRESS) extern uint32_t _image_1_primary_slot_id[]; -#endif -#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) +#endif /* (MCUBOOT_IMAGE_NUMBER == 2 && defined(PM_B0_ADDRESS) */ -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) -#elif defined(PM_B0_ADDRESS) +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) #define FLASH_AREA_IMAGE_PRIMARY(x) \ ((x == 0) ? \ @@ -56,26 +38,52 @@ extern uint32_t _image_1_primary_slot_id[]; (x == 1) ? \ PM_MCUBOOT_SECONDARY_ID: \ 255 ) + +#else /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + */ + +/* Each pair of slots is separated by , and there is no terminating character */ +#define FLASH_AREA_IMAGE_0_SLOTS PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID +#define FLASH_AREA_IMAGE_1_SLOTS PM_MCUBOOT_PRIMARY_1_ID, PM_MCUBOOT_SECONDARY_1_ID +#define FLASH_AREA_IMAGE_2_SLOTS PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID + +#if (MCUBOOT_IMAGE_NUMBER == 1) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS +#elif (MCUBOOT_IMAGE_NUMBER == 2) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ + FLASH_AREA_IMAGE_1_SLOTS +#elif (MCUBOOT_IMAGE_NUMBER == 3) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ + FLASH_AREA_IMAGE_1_SLOTS, \ + FLASH_AREA_IMAGE_2_SLOTS #else +#error Unsupported number of images +#endif -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) +static inline uint32_t __flash_area_ids_for_slot(int img, int slot) +{ + static const int all_slots[] = { + ALL_AVAILABLE_SLOTS + }; + return all_slots[img * 2 + slot]; +}; -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) +#undef FLASH_AREA_IMAGE_0_SLOTS +#undef FLASH_AREA_IMAGE_1_SLOTS +#undef FLASH_AREA_IMAGE_2_SLOTS +#undef ALL_AVAILABLE_SLOTS -#endif /* PM_B0_ADDRESS */ +#define FLASH_AREA_IMAGE_PRIMARY(x) __flash_area_ids_for_slot(x, 0) +#define FLASH_AREA_IMAGE_SECONDARY(x) __flash_area_ids_for_slot(x, 1) +#if !defined(CONFIG_BOOT_SWAP_USING_MOVE) +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID #endif -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID + +#endif /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + */ #else /* CONFIG_SINGLE_APPLICATION_SLOT */ From 51e36d84b97b8de93f6b5b73dc81040616c2858a Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 15 Feb 2024 16:47:25 +0100 Subject: [PATCH 194/238] [nrf noup] loader: introduced cleanup of unusable secondary slot Added procedure which clean-up content of all the secondary slot which contains valid header but couldn't be assigned to any of supported primary images. This behavior is needed when configuration allows to use one secondary slot for collecting image for multiple primary slots. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 8f4b472b810dbe0a6fda02d2856efa42985bea09) --- boot/bootutil/src/loader.c | 90 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index c43b64d06..cec4eec27 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1240,6 +1240,87 @@ boot_update_security_counter(uint8_t image_index, int slot, } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ +#if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ +(defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP)) + +#define SEC_SLOT_VIRGIN 0 +#define SEC_SLOT_TOUCHED 1 +#define SEC_SLOT_ASSIGNED 2 + +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +/* This configuration is peculiar - the one physical secondary slot is + * mocking two logical secondary + */ +#define SEC_SLOT_PHYSICAL_CNT 1 +#else +#define SEC_SLOT_PHYSICAL_CNT MCUBOOT_IMAGE_NUMBER +#endif + +static uint8_t sec_slot_assignmnet[SEC_SLOT_PHYSICAL_CNT] = {0}; + +static inline void sec_slot_touch(struct boot_loader_state *state) +{ + uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); + + if (SEC_SLOT_VIRGIN == sec_slot_assignmnet[idx]) { + sec_slot_assignmnet[idx] = SEC_SLOT_TOUCHED; + } +} + +static inline void sec_slot_mark_assigned(struct boot_loader_state *state) +{ + uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); + + sec_slot_assignmnet[idx] = SEC_SLOT_ASSIGNED; +} + +/** + * Cleanu up all secondary slot which couldn't be assigned to any primary slot. + * + * This function erases content of each secondary slot which contains valid + * header but couldn't be assigned to any of supported primary images. + * + * This function is supposed to be called after boot_validated_swap_type() + * iterates over all the images in context_boot_go(). + */ +static void sec_slot_cleanup_if_unusable(void) +{ + uint8_t idx; + + for (idx = 0; idx < SEC_SLOT_PHYSICAL_CNT; idx++) { + if (SEC_SLOT_TOUCHED == sec_slot_assignmnet[idx]) { + const struct flash_area *secondary_fa; + int rc; + + rc = flash_area_open(flash_area_id_from_multi_image_slot(idx, BOOT_SECONDARY_SLOT), + &secondary_fa); + if (!rc) { + rc = flash_area_erase(secondary_fa, 0, secondary_fa->fa_size); + if (!rc) { + BOOT_LOG_ERR("Cleaned-up secondary slot of %d. image.", idx); + } + } + + if (rc) { + BOOT_LOG_ERR("Can not cleanup secondary slot of %d. image.", idx); + } + } + } +} +#else +static inline void sec_slot_touch(struct boot_loader_state *state) +{ +} +static inline void sec_slot_mark_assigned(struct boot_loader_state *state) +{ +} +static inline void sec_slot_cleanup_if_unusable(void) +{ +} +#endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ + defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */ + #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) /** * Determines which swap operation to perform, if any. If it is determined @@ -1278,6 +1359,9 @@ boot_validated_swap_type(struct boot_loader_state *state, if (rc != 0) { return BOOT_SWAP_TYPE_FAIL; } + + sec_slot_touch(state); + #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS if(reset_addr < PM_CPUNET_B0N_ADDRESS) @@ -1312,6 +1396,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } #else return BOOT_SWAP_TYPE_NONE; + #endif } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { @@ -1320,7 +1405,9 @@ boot_validated_swap_type(struct boot_loader_state *state, } } #endif /* PM_S1_ADDRESS */ + sec_slot_mark_assigned(state); } + #endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); @@ -2450,6 +2537,9 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } } + /* cleanup secondary slots which were recognized unusable*/ + sec_slot_cleanup_if_unusable(); + #if (BOOT_IMAGE_NUMBER > 1) if (has_upgrade) { /* Iterate over all the images and verify whether the image dependencies From 592a0f140c5c9bc6ec3a436f03ab0249454cabf2 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Tue, 16 Apr 2024 16:10:55 +0200 Subject: [PATCH 195/238] [nrf noup] boards: nrf54l15: Disable FPROTECT FPROTECT is not suppored yet for nrf54l15. Signed-off-by: Grzegorz Chwierut Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 0b5810de95eb93bbd4fba8e20a2152b33880fc43) --- boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf index 43d8cebe3..8d8eb845f 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -7,4 +7,7 @@ CONFIG_BOOT_MAX_IMG_SECTORS=256 # Ensure that the SPI NOR driver is disabled by default CONFIG_SPI_NOR=n +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + CONFIG_BOOT_WATCHDOG_FEED=n From 948c3ad530822e58aae826984bae961626f4cca1 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Fri, 17 May 2024 18:25:07 +0200 Subject: [PATCH 196/238] [nrf noup] loader: remove cleanup for direct xip mode Move ifdefs just to not add code for cleanup unusable slot when direct xip mode is enabled to avoid warnings. Signed-off-by: Grzegorz Chwierut (cherry picked from commit 650d11c32368d8ddea310fcdf0d52b45d9017f15) --- boot/bootutil/src/loader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index cec4eec27..705c85052 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1240,6 +1240,8 @@ boot_update_security_counter(uint8_t image_index, int slot, } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ +#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) + #if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ (defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP)) @@ -1321,7 +1323,6 @@ static inline void sec_slot_cleanup_if_unusable(void) #endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */ -#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) /** * Determines which swap operation to perform, if any. If it is determined * that a swap operation is required, the image in the secondary slot is checked From a3545cda5726ce5af126cf094d415f23a427c1eb Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 19 Apr 2024 16:33:07 +0000 Subject: [PATCH 197/238] [nrf noup] zephyr: Clean up non-secure RAM if enabled fixup! [nrf noup] zephyr: Clean up non-secure RAM if enabled Add support for nrf54l15 UARTE20 and UARTE30. Signed-off-by: Dominik Ermel (cherry picked from commit 0611b4c3feba6328e09b19f23a879dbc78b5d174) --- boot/zephyr/nrf_cleanup.c | 66 +++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 2165159ea..051705ec9 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -5,9 +5,8 @@ */ #include -#if defined(NRF_UARTE0) || defined(NRF_UARTE1) - #include -#endif +#include +#include #if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) #include #endif @@ -24,6 +23,11 @@ #include #endif +#if defined(NRF_UARTE0) || defined(NRF_UARTE1) || defined(NRF_UARTE20) || \ + defined(NRF_UARTE30) +#define NRF_UARTE_CLEANUP +#endif + #define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) #define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ NRF_UARTE_SUBSCRIBE_CONF_OFFS) @@ -41,6 +45,23 @@ static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) } #endif +#if defined(NRF_UARTE_CLEANUP) +static NRF_UARTE_Type *nrf_uarte_to_clean[] = { +#if defined(NRF_UARTE0) + NRF_UARTE0, +#endif +#if defined(NRF_UARTE1) + NRF_UARTE1, +#endif +#if defined(NRF_UARTE20) + NRF_UARTE20, +#endif +#if defined(NRF_UARTE30) + NRF_UARTE30, +#endif +}; +#endif + static void nrf_cleanup_clock(void) { nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); @@ -57,26 +78,31 @@ void nrf_cleanup_peripheral(void) #if defined(NRF_RTC2) nrf_cleanup_rtc(NRF_RTC2); #endif -#if defined(NRF_UARTE0) - nrf_uarte_disable(NRF_UARTE0); - nrf_uarte_int_disable(NRF_UARTE0, 0xFFFFFFFF); -#if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); -#endif -#endif -#if defined(NRF_UARTE1) - nrf_uarte_disable(NRF_UARTE1); - nrf_uarte_int_disable(NRF_UARTE1, 0xFFFFFFFF); + +#if defined(NRF_UARTE_CLEANUP) + for (int i = 0; i < sizeof(nrf_uarte_to_clean) / sizeof(nrf_uarte_to_clean[0]); ++i) { + NRF_UARTE_Type *current = nrf_uarte_to_clean[i]; + + nrfy_uarte_int_disable(current, 0xFFFFFFFF); + nrfy_uarte_int_uninit(current); + nrfy_uarte_task_trigger(current, NRF_UARTE_TASK_STOPRX); + + nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXSTARTED); + nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_ENDRX); + nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXTO); + nrfy_uarte_disable(current); + #if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)current + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, + NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)current + NRF_UARTE_PUBLISH_CONF_OFFS, 0, + NRF_UARTE_PUBLISH_CONF_SIZE); #endif + } #endif + #if defined(NRF_PPI) nrf_ppi_channels_disable_all(NRF_PPI); #endif From 1347dfbdc7b756eaac18d436f04f8755d57867a2 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 15 Apr 2024 18:54:45 +0200 Subject: [PATCH 198/238] [nrf noup] boot/zephyr/boards: nrf54l15pdk ext-flash partition Added DTS with partitioning which involves external flash as place for slo1_partition. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit efe6681e7a6f6b121d5c3c6b40af828fbde9baf7) --- ...54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index 2341ffd26..76b648903 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -4,7 +4,42 @@ }; }; +/delete-node/ &boot_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +/delete-node/ &slot0_ns_partition; +/delete-node/ &slot1_ns_partition; + +/delete-node/ &storage_partition; + +&rram0 { + partitions { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x000000000 0x00014000>; + }; + slot0_partition: partition@14000 { + label = "image-0"; + reg = <0x000014000 0x0015A000>; + }; + storage_partition: partition@16E000 { + label = "storage"; + reg = < 0x16E000 0x9000 >; + }; + }; +}; &mx25r64 { status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + slot1_partition: partition@0 { + label = "image-1"; + reg = <0x000000000 0x0015A000>; + }; + }; }; From 8b7d37ff71b7306632186bfedc8fdd306f842fed Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 20 May 2024 15:48:33 +0200 Subject: [PATCH 199/238] [nrf noup] boot/zephyr/boards: nrf54l15pdk ext-flash update This patch supplements the configuration for external flash so MCUboot can be build with FILE_SUFFIX="ext_flash" for the nrf54l15pdk instead of explicitly configuration specification. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 3131c92c5109266145fdc0528bf3991d6709a6a6) --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf | 7 +++++++ .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 1 + 2 files changed, 8 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf index 841922dbd..8fc12e074 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf @@ -6,3 +6,10 @@ CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 CONFIG_MAIN_STACK_SIZE=20480 CONFIG_BOOT_MAX_IMG_SECTORS=512 CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +# Ensure that the qspi driver is disabled by default +CONFIG_NORDIC_QSPI_NOR=n + +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + +CONFIG_BOOT_WATCHDOG_FEED=n diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index 76b648903..ea024fcec 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -1,6 +1,7 @@ / { chosen { nordic,pm-ext-flash = &mx25r64; + zephyr,code-partition = &boot_partition; }; }; From 6b95cd61058b116dcf9f186b5490b925230e3d3d Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Tue, 12 Mar 2024 12:30:52 +0100 Subject: [PATCH 200/238] [nrf noup] boards: thingy91x: enable serial recovery This patch disbales MCUBoot logging and enables serial recovery for the Thingy:91. Signed-off-by: Maximilian Deubel Signed-off-by: Bernt Johan Damslora (cherry picked from commit f67a11a8b4f6fff87641be346c4744ea059bffd7) --- boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf | 10 ++++++++-- boot/zephyr/boards/thingy91x_nrf9151.conf | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf index 72dfa7fca..37c7e95b1 100644 --- a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf @@ -32,7 +32,7 @@ CONFIG_USB_COMPOSITE_DEVICE=y CONFIG_USB_MASS_STORAGE=n CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x520F +CONFIG_USB_DEVICE_PID=0x910A CONFIG_BOOT_SERIAL_BOOT_MODE=y @@ -49,6 +49,12 @@ CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y CONFIG_FLASH_SIMULATOR_STATS=n CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y -CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +# Makes it possible to update the network core using the flash simulator CONFIG_NRF53_RECOVERY_NETWORK_CORE=y + +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y + +# Skip checks on the secondary image to make it possible to update MCUBoot on S1/S0 +CONFIG_MCUBOOT_VERIFY_IMG_ADDRESS=n diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf index 33cd3301c..2efe1e170 100644 --- a/boot/zephyr/boards/thingy91x_nrf9151.conf +++ b/boot/zephyr/boards/thingy91x_nrf9151.conf @@ -6,3 +6,12 @@ CONFIG_SPI_NOR=y CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 CONFIG_SPI_NOR_SFDP_DEVICETREE=y CONFIG_MULTITHREADING=y + +# Disable Zephyr console and use UART for MCUboot serial recovery instead +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n +CONFIG_MCUBOOT_SERIAL=y + +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y From 220096b278e3c1ddb91249920d12688626e4a02e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 17 May 2024 14:14:54 +0200 Subject: [PATCH 201/238] [nrf noup] boot: zephyr: Disable boot banner if NCS_BOOT_BANNER is used Mcuboot's boot banner should not be used if NCS boot banner is enabled. Signed-off-by: Robert Lubos (cherry picked from commit 7b018cb85202d7d46abcdcd496c7f5d1afa2a2d5) --- boot/zephyr/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index ffacd44b1..5ac2bb49a 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -717,6 +717,7 @@ config BOOT_DISABLE_CACHES config MCUBOOT_BOOT_BANNER bool "Use MCUboot boot banner" depends on BOOT_BANNER + depends on !NCS_BOOT_BANNER depends on "$(APP_VERSION_EXTENDED_STRING)" != "" default y help From 592f636c54a3b4c702c8e90a0d791ab1f00c4082 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 27 May 2024 13:59:49 +0200 Subject: [PATCH 202/238] [nrf noup] boot/zephyr: fix fw_info search By the upstream patch the vt get now the pointer to the copy of the arm_vector instead of original. This patch fixes address of the firmware which is to be taken by the fw_info_find. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 3be724f5537c53b6ba6ef6e6b34cad0f961c50ff) --- boot/zephyr/main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 4c3f47ee5..13ee24aad 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -206,7 +206,14 @@ static void do_boot(struct boot_rsp *rsp) #endif #if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - const struct fw_info *firmware_info = fw_info_find((uint32_t) vt); + uintptr_t fw_start_addr; + + rc = flash_device_base(rsp->br_flash_dev_id, &fw_start_addr); + assert(rc == 0); + + fw_start_addr += rsp->br_image_off + rsp->br_hdr->ih_hdr_size; + + const struct fw_info *firmware_info = fw_info_find(fw_start_addr); bool provided = fw_info_ext_api_provide(firmware_info, true); #ifdef PM_S0_ADDRESS From ad758099070ad3c3ff157e1dd9f7a7cd96abc8f4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 28 May 2024 09:31:16 +0000 Subject: [PATCH 203/238] [nrf noup] Revert of zephyr: arm: Update reading the flash image reset vector This is revert of upstream commit 453096b17ddc3aac7bf6afb97c40591d5ea3aa9c which was supposed to allow picking interrupt vector table from flash area but the whole modification unfortunately misunderstood difference between flash device ID and flash area ID. The commit is not important for sdk-nrf and requires re-design and fixing upstream. Signed-off-by: Dominik Ermel (cherry picked from commit f1e1675630561a745d28107144e9a863860204cf) --- boot/zephyr/flash_map_extended.c | 8 ++------ boot/zephyr/main.c | 20 +++++--------------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c index 4631da75b..d0744afbd 100644 --- a/boot/zephyr/flash_map_extended.c +++ b/boot/zephyr/flash_map_extended.c @@ -141,12 +141,8 @@ int flash_area_sector_from_off(off_t off, struct flash_sector *sector) uint8_t flash_area_get_device_id(const struct flash_area *fa) { -#if defined(CONFIG_ARM) - return fa->fa_id; -#else - (void)fa; - return FLASH_DEVICE_ID; -#endif + (void)fa; + return FLASH_DEVICE_ID; } #define ERASED_VAL 0xff diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 13ee24aad..b2d0ea8a1 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -174,26 +174,16 @@ static void do_boot(struct boot_rsp *rsp) /* Get ram address for image */ vt = (struct arm_vector_table *)(rsp->br_hdr->ih_load_addr + rsp->br_hdr->ih_hdr_size); #else + uintptr_t flash_base; int rc; - const struct flash_area *fap; - static uint32_t dst[2]; /* Jump to flash image */ - rc = flash_area_open(rsp->br_flash_dev_id, &fap); - assert(rc == 0); - - rc = flash_area_read(fap, rsp->br_hdr->ih_hdr_size, dst, sizeof(dst)); + rc = flash_device_base(rsp->br_flash_dev_id, &flash_base); assert(rc == 0); -#ifndef CONFIG_ASSERT - /* Enter a lock up as asserts are disabled */ - if (rc != 0) { - while (1); - } -#endif - - flash_area_close(fap); - vt = (struct arm_vector_table *)dst; + vt = (struct arm_vector_table *)(flash_base + + rsp->br_image_off + + rsp->br_hdr->ih_hdr_size); #endif if (IS_ENABLED(CONFIG_SYSTEM_TIMER_HAS_DISABLE_SUPPORT)) { From 48e6e27175230a817fc47857696b006ddd15f6f3 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Wed, 5 Jun 2024 15:46:13 +0200 Subject: [PATCH 204/238] [nrf noup] zephyr/boards: fix nrf54l15pdk ext flash dts overlay Align to changes in DTS: renamed: rram0 -> cpuapp_rram sized up cpauapp_rram region szie as part of it was reserved for cpuflpr_rram (which is not used by this config). Signed-off-by: Andrzej Puzdrowski (cherry picked from commit f1c2b8cb41cbeedbc625fdec7f9f29e91eec0c8d) --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index ea024fcec..60ee6fe51 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -14,7 +14,8 @@ /delete-node/ &storage_partition; -&rram0 { +&cpuapp_rram { + reg = < 0x0 DT_SIZE_K(1524) >; partitions { boot_partition: partition@0 { label = "mcuboot"; From 0148f9641558629109d6e073740a2e7f2cd06e1d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 11 Jun 2024 12:32:51 +0100 Subject: [PATCH 205/238] [nrf noup] boot: zephyr: Add NCS boot banner Adds a boot banner which shows as MCUboot Signed-off-by: Jamie McCrae (cherry picked from commit 6869a65c9171849f1c50407b924e875fcc9d6e92) --- boot/zephyr/prj.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 23b5f3b93..e4f7d9030 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -37,3 +37,6 @@ CONFIG_CBPRINTF_NANO=y ### Use the minimal C library to reduce flash usage CONFIG_MINIMAL_LIBC=y CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 + +# NCS boot banner +CONFIG_NCS_APPLICATION_BOOT_BANNER_STRING="MCUboot" From cc781180dd791b4ac7d9c875cf8ada38a2de0a12 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 13 Jun 2024 16:34:55 +0200 Subject: [PATCH 206/238] [nrf noup] boot/../loader: skip downgrade prevention for s1/s0 This patch introduces skip on checking downgrade for s1/s0 upgrade image (chain-loaded by NSIB). which is used for upgrade MCUboot instance itself. Reason is that sdk-mcuboot has not access to semantic version of its own image. I also shouldn't touch HW counter used for hardware downgrade prevention for the application image (which was the case). HW counters for s0/s1 image are owned by NSIB because its role is to prevnt dongrades of s0/s1 MCUboot. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 776ee26039e6aec64b65ee393c93e5cda2d1a7b2) --- boot/bootutil/src/loader.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 705c85052..9bae1bdbc 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -70,6 +70,9 @@ int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); BOOT_LOG_MODULE_DECLARE(mcuboot); static struct boot_loader_state boot_data; +#ifdef PM_S1_ADDRESS +static bool owner_nsib[BOOT_IMAGE_NUMBER] = {false}; +#endif #if defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO) || defined(MCUBOOT_DATA_SHARING) static struct image_max_size image_max_sizes[BOOT_IMAGE_NUMBER] = {0}; @@ -1338,6 +1341,9 @@ boot_validated_swap_type(struct boot_loader_state *state, int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); bool upgrade_valid = false; +#if defined(PM_S1_ADDRESS) + owner_nsib[BOOT_CURR_IMG(state)] = false; +#endif #if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) const struct flash_area *secondary_fa = @@ -1394,6 +1400,7 @@ boot_validated_swap_type(struct boot_loader_state *state, && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { /* Set primary to be NSIB upgrade slot */ BOOT_IMG_AREA(state, 0) = nsib_fa; + owner_nsib[BOOT_CURR_IMG(state)] = true; } #else return BOOT_SWAP_TYPE_NONE; @@ -1404,6 +1411,10 @@ boot_validated_swap_type(struct boot_loader_state *state, /* The image in the secondary slot is not intended for any */ return BOOT_SWAP_TYPE_NONE; } + + if ((primary_fa->fa_off == PM_S0_ADDRESS) || (primary_fa->fa_off == PM_S1_ADDRESS)) { + owner_nsib[BOOT_CURR_IMG(state)] = true; + } } #endif /* PM_S1_ADDRESS */ sec_slot_mark_assigned(state); @@ -2371,6 +2382,13 @@ check_downgrade_prevention(struct boot_loader_state *state) uint32_t security_counter[2]; int rc; +#if defined(PM_S1_ADDRESS) + if (owner_nsib[BOOT_CURR_IMG(state)]) { + /* Downgrade prevention on S0/S1 image is managed by NSIB */ + return 0; + } +#endif + if (MCUBOOT_DOWNGRADE_PREVENTION_SECURITY_COUNTER) { /* If there was security no counter in slot 0, allow swap */ rc = bootutil_get_img_security_cnt(&(BOOT_IMG(state, 0).hdr), From 29fdb635a4fd7fab89281a1204383bc73c20c63f Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Tue, 18 Jun 2024 17:35:41 +0200 Subject: [PATCH 207/238] [nrf noup] boot/../loader: reboot after updating s0/s1 As this is MCUboot updating itself, it should reboot the device so NSIB will chainload the update MCUboot Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 85419552247489623522d64b605310751becda67) --- boot/bootutil/src/loader.c | 10 ++++++++++ boot/zephyr/Kconfig | 1 + 2 files changed, 11 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 9bae1bdbc..dd53619b1 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,6 +49,10 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" +#ifdef __ZEPHYR__ +#include +#endif + #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) #include #ifdef CONFIG_PCD_READ_NETCORE_APP_VERSION @@ -2627,6 +2631,12 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) rc = boot_perform_update(state, &bs); } assert(rc == 0); +#if defined(PM_S1_ADDRESS) && defined(CONFIG_REBOOT) + if (owner_nsib[BOOT_CURR_IMG(state)]) { + sys_reboot(SYS_REBOOT_COLD); + + } +#endif break; case BOOT_SWAP_TYPE_FAIL: diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 5ac2bb49a..dded93010 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -18,6 +18,7 @@ config MCUBOOT select MPU_ALLOW_FLASH_WRITE if ARM_MPU select USE_DT_CODE_PARTITION if HAS_FLASH_LOAD_OFFSET select MCUBOOT_BOOTUTIL_LIB + select REBOOT if SECURE_BOOT config BOOT_USE_MBEDTLS bool From 28fdae884d9ded5f320febd57b96b0a0fd5eb638 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 4 Sep 2024 08:07:38 +0100 Subject: [PATCH 208/238] [nrf noup] Remove secure boot debug Kconfig fixup! [nrf noup] zephyr: add 'minimal' configuration files Removes setting a now removed Kconfig option Signed-off-by: Jamie McCrae --- boot/zephyr/prj_minimal.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/prj_minimal.conf b/boot/zephyr/prj_minimal.conf index 1f90e708b..55d4c6167 100644 --- a/boot/zephyr/prj_minimal.conf +++ b/boot/zephyr/prj_minimal.conf @@ -34,7 +34,6 @@ CONFIG_NCS_SAMPLES_DEFAULTS=n CONFIG_NO_RUNTIME_CHECKS=y CONFIG_NRF_RTC_TIMER=n CONFIG_PRINTK=n -CONFIG_SECURE_BOOT_DEBUG=n CONFIG_SERIAL=n CONFIG_SIZE_OPTIMIZATIONS=y CONFIG_SYS_CLOCK_EXISTS=n From fcf0a3154845a17d90abd767b35716d1dee96df4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 29 Aug 2024 12:41:37 +0100 Subject: [PATCH 209/238] [nrf noup] bootutil: loader: Fix netcore address checking Fixes an issues with wrongly checking the network core reset address Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index dd53619b1..5471403f0 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1375,7 +1375,7 @@ boot_validated_swap_type(struct boot_loader_state *state, #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS - if(reset_addr < PM_CPUNET_B0N_ADDRESS) + if(!(reset_addr >= PM_CPUNET_APP_ADDRESS && reset_addr < PM_CPUNET_APP_END_ADDRESS)) #endif { const struct flash_area *primary_fa; @@ -1448,7 +1448,8 @@ boot_validated_swap_type(struct boot_loader_state *state, * update and indicate to the caller of this function that no update is * available */ - if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { + if (upgrade_valid && reset_addr >= PM_CPUNET_APP_ADDRESS && + reset_addr < PM_CPUNET_APP_END_ADDRESS) { struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr); From 123454f993b1dd08e9f158ee4df95247a1ea81d9 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Wed, 18 Sep 2024 12:28:37 +0200 Subject: [PATCH 210/238] [nrf noup] boards: nrf54l15dk: Disable FPROTECT FPROTECT is not suppored for nrf54l15dk. Signed-off-by: Andrzej Puzdrowski --- boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf index 43d8cebe3..8d8eb845f 100644 --- a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf +++ b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf @@ -7,4 +7,7 @@ CONFIG_BOOT_MAX_IMG_SECTORS=256 # Ensure that the SPI NOR driver is disabled by default CONFIG_SPI_NOR=n +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + CONFIG_BOOT_WATCHDOG_FEED=n From a242e9124370dce206f7933a4f85a707e07c915f Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 22 Aug 2024 14:17:46 +0100 Subject: [PATCH 211/238] [nrf noup] zephyr: Add support for compressed image updates Adds support for LZMA-compressed firmware updates Signed-off-by: Jamie McCrae --- boot/bootutil/src/image_validate.c | 224 ++++ boot/bootutil/src/loader.c | 102 +- boot/zephyr/CMakeLists.txt | 6 + boot/zephyr/Kconfig | 5 + boot/zephyr/decompression.c | 1105 +++++++++++++++++ .../include/compression/decompression.h | 104 ++ 6 files changed, 1525 insertions(+), 21 deletions(-) create mode 100644 boot/zephyr/decompression.c create mode 100644 boot/zephyr/include/compression/decompression.h diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 5953658b0..1811cdb87 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -40,6 +40,15 @@ #include "mcuboot_config/mcuboot_config.h" +#if defined(MCUBOOT_DECOMPRESS_IMAGES) +#include +#include +#endif + +#include "bootutil/bootutil_log.h" + +BOOT_LOG_MODULE_DECLARE(mcuboot); + #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" #endif @@ -415,6 +424,66 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, FIH_DECLARE(security_counter_valid, FIH_FAILURE); #endif +#ifdef MCUBOOT_DECOMPRESS_IMAGES + /* If the image is compressed, the integrity of the image must also be validated */ + if (MUST_DECOMPRESS(fap, image_index, hdr)) { + bool found_decompressed_size = false; + bool found_decompressed_sha = false; + bool found_decompressed_signature = false; + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, true); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(fap)) { + rc = -1; + goto out; + } + + while (true) { + uint16_t expected_size = 0; + bool *found_flag = NULL; + + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + break; + } + + switch (type) { + case IMAGE_TLV_DECOMP_SIZE: + expected_size = sizeof(size_t); + found_flag = &found_decompressed_size; + break; + case IMAGE_TLV_DECOMP_SHA: + expected_size = IMAGE_HASH_SIZE; + found_flag = &found_decompressed_sha; + break; + case IMAGE_TLV_DECOMP_SIGNATURE: + expected_size = SIG_BUF_SIZE; + found_flag = &found_decompressed_signature; + break; + default: + continue; + }; + + if (len != expected_size) { + rc = -1; + goto out; + } + + *found_flag = true; + } + + rc = (!found_decompressed_size || !found_decompressed_sha || !found_decompressed_signature); + if (rc) { + goto out; + } + } +#endif + rc = bootutil_img_hash(enc_state, image_index, hdr, fap, tmp_buf, tmp_buf_sz, hash, seed, seed_len); if (rc) { @@ -586,6 +655,161 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } #endif +#ifdef MCUBOOT_DECOMPRESS_IMAGES + /* Only after all previous verifications have passed, perform a dry-run of the decompression + * and ensure the image is valid + */ + if (!rc && MUST_DECOMPRESS(fap, image_index, hdr)) { + image_hash_valid = 0; + FIH_SET(valid_signature, FIH_FAILURE); + + rc = bootutil_img_hash_decompress(enc_state, image_index, hdr, fap, tmp_buf, tmp_buf_sz, + hash, seed, seed_len); + if (rc) { + goto out; + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SHA, true); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(fap)) { + rc = -1; + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + break; + } + + if (type == IMAGE_TLV_DECOMP_SHA) { + /* Verify the image hash. This must always be present. */ + if (len != sizeof(hash)) { + rc = -1; + goto out; + } + rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, sizeof(hash)); + if (rc) { + goto out; + } + + FIH_CALL(boot_fih_memequal, fih_rc, hash, buf, sizeof(hash)); + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + + image_hash_valid = 1; + } + } + + rc = !image_hash_valid; + if (rc) { + goto out; + } + +#ifdef EXPECTED_SIG_TLV +#ifdef EXPECTED_KEY_TLV + rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_KEY_TLV, false); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(fap)) { + rc = -1; + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + break; + } + + if (type == EXPECTED_KEY_TLV) { + /* + * Determine which key we should be checking. + */ + if (len > KEY_BUF_SIZE) { + rc = -1; + goto out; + } +#ifndef MCUBOOT_HW_KEY + rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, len); + if (rc) { + goto out; + } + key_id = bootutil_find_key(buf, len); +#else + rc = LOAD_IMAGE_DATA(hdr, fap, off, key_buf, len); + if (rc) { + goto out; + } + key_id = bootutil_find_key(image_index, key_buf, len); +#endif /* !MCUBOOT_HW_KEY */ + /* + * The key may not be found, which is acceptable. There + * can be multiple signatures, each preceded by a key. + */ + } + } +#endif /* EXPECTED_KEY_TLV */ + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIGNATURE, true); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(fap)) { + rc = -1; + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIGNATURE) { + /* Ignore this signature if it is out of bounds. */ + if (key_id < 0 || key_id >= bootutil_key_cnt) { + key_id = -1; + continue; + } + + if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) { + rc = -1; + goto out; + } + rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, len); + if (rc) { + goto out; + } + + FIH_CALL(bootutil_verify_sig, valid_signature, hash, sizeof(hash), + buf, len, key_id); + key_id = -1; + } + } +#endif /* EXPECTED_SIG_TLV */ + } +#endif + +#ifdef EXPECTED_SIG_TLV + FIH_SET(fih_rc, valid_signature); +#endif + out: if (rc) { FIH_SET(fih_rc, FIH_FAILURE); diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 5471403f0..5dfd0419f 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,6 +49,11 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" +#if defined(MCUBOOT_DECOMPRESS_IMAGES) +#include +#include +#endif + #ifdef __ZEPHYR__ #include #endif @@ -583,35 +588,76 @@ boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size) goto done; } - off = BOOT_TLV_OFF(boot_img_hdr(state, slot)); +#ifdef MCUBOOT_DECOMPRESS_IMAGES + if (MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), boot_img_hdr(state, slot))) { + uint32_t tmp_size = 0; - if (flash_area_read(fap, off, &info, sizeof(info))) { - rc = BOOT_EFLASH; - goto done; - } + rc = bootutil_get_img_decomp_size(boot_img_hdr(state, slot), fap, &tmp_size); + + if (rc) { + rc = BOOT_EBADIMAGE; + goto done; + } + + off = boot_img_hdr(state, slot)->ih_hdr_size + tmp_size; - protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size; - if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { - if (protect_tlv_size != info.it_tlv_tot) { + rc = boot_size_protected_tlvs(boot_img_hdr(state, slot), fap, &tmp_size); + + if (rc) { rc = BOOT_EBADIMAGE; goto done; } - if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) { + off += tmp_size; + + if (flash_area_read(fap, (BOOT_TLV_OFF(boot_img_hdr(state, slot)) + + boot_img_hdr(state, slot)->ih_protect_tlv_size), &info, + sizeof(info))) { rc = BOOT_EFLASH; goto done; } - } else if (protect_tlv_size != 0) { - rc = BOOT_EBADIMAGE; - goto done; - } - if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { - rc = BOOT_EBADIMAGE; - goto done; + if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { + rc = BOOT_EBADIMAGE; + goto done; + } + + *size = off + info.it_tlv_tot; + } else { +#else + if (1) { +#endif + off = BOOT_TLV_OFF(boot_img_hdr(state, slot)); + + if (flash_area_read(fap, off, &info, sizeof(info))) { + rc = BOOT_EFLASH; + goto done; + } + + protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size; + if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { + if (protect_tlv_size != info.it_tlv_tot) { + rc = BOOT_EBADIMAGE; + goto done; + } + + if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) { + rc = BOOT_EFLASH; + goto done; + } + } else if (protect_tlv_size != 0) { + rc = BOOT_EBADIMAGE; + goto done; + } + + if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { + rc = BOOT_EBADIMAGE; + goto done; + } + + *size = off + protect_tlv_size + info.it_tlv_tot; } - *size = off + protect_tlv_size + info.it_tlv_tot; rc = 0; done: @@ -938,10 +984,10 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa return false; } #else - if ((hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1) && - (hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) - { - return false; + if (MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), hdr)) { + if (!boot_is_compressed_header_valid(hdr, fap, state)) { + return false; + } } #endif @@ -1121,6 +1167,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * attempts to validate and boot it. */ } + #if !defined(__BOOTSIM__) BOOT_LOG_ERR("Image in the %s slot is not valid!", (slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary"); @@ -1557,6 +1604,9 @@ boot_copy_region(struct boot_loader_state *state, #else (void)state; #endif +#ifdef MCUBOOT_DECOMPRESS_IMAGES + struct image_header *hdr; +#endif TARGET_STATIC uint8_t buf[BUF_SZ] __attribute__((aligned(4))); @@ -1582,6 +1632,16 @@ boot_copy_region(struct boot_loader_state *state, } #endif +#ifdef MCUBOOT_DECOMPRESS_IMAGES + hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + + if (MUST_DECOMPRESS(fap_src, BOOT_CURR_IMG(state), hdr)) { + /* Use alternative function for compressed images */ + return boot_copy_region_decompress(state, fap_src, fap_dst, off_src, off_dst, sz, buf, + BUF_SZ); + } +#endif + bytes_copied = 0; while (bytes_copied < sz) { if (sz - bytes_copied > sizeof buf) { diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 1d3009b22..253ab2537 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -249,6 +249,12 @@ if(CONFIG_BOOT_ENCRYPT_EC256) ) endif() +if(CONFIG_BOOT_DECOMPRESSION) + zephyr_library_sources( + decompression.c + ) +endif() + if(CONFIG_MCUBOOT_SERIAL) zephyr_sources(${BOOT_DIR}/zephyr/serial_adapter.c) zephyr_sources(${BOOT_DIR}/boot_serial/src/boot_serial.c) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index dded93010..6fe786c07 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -735,6 +735,10 @@ config BOOT_BANNER_STRING config BOOT_DECOMPRESSION_SUPPORT bool + depends on NRF_COMPRESS && NRF_COMPRESS_DECOMPRESSION && (NRF_COMPRESS_LZMA_VERSION_LZMA1 || NRF_COMPRESS_LZMA_VERSION_LZMA2) + depends on !SINGLE_APPLICATION_SLOT && !BOOT_ENCRYPT_IMAGE && BOOT_UPGRADE_ONLY + depends on UPDATEABLE_IMAGE_NUMBER = 1 + default y help Hidden symbol which should be selected if a system provided decompression support. @@ -742,6 +746,7 @@ if BOOT_DECOMPRESSION_SUPPORT menuconfig BOOT_DECOMPRESSION bool "Decompression" + select NRF_COMPRESS_CLEANUP help If enabled, will include support for compressed images being loaded to the secondary slot which then get decompressed into the primary slot. This mode allows the secondary slot to diff --git a/boot/zephyr/decompression.c b/boot/zephyr/decompression.c new file mode 100644 index 000000000..5d491adcf --- /dev/null +++ b/boot/zephyr/decompression.c @@ -0,0 +1,1105 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include "compression/decompression.h" +#include "bootutil/crypto/sha.h" +#include "bootutil/bootutil_log.h" + +#if !defined(__BOOTSIM__) +#define TARGET_STATIC static +#else +#define TARGET_STATIC +#endif + +#if defined(MCUBOOT_SIGN_RSA) +#if MCUBOOT_SIGN_RSA_LEN == 2048 +#define EXPECTED_SIG_TLV IMAGE_TLV_RSA2048_PSS +#elif MCUBOOT_SIGN_RSA_LEN == 3072 +#define EXPECTED_SIG_TLV IMAGE_TLV_RSA3072_PSS +#endif +#elif defined(MCUBOOT_SIGN_EC256) || \ + defined(MCUBOOT_SIGN_EC384) || \ + defined(MCUBOOT_SIGN_EC) +#define EXPECTED_SIG_TLV IMAGE_TLV_ECDSA_SIG +#elif defined(MCUBOOT_SIGN_ED25519) +#define EXPECTED_SIG_TLV IMAGE_TLV_ED25519 +#endif + +/* Number of times that consumed data by decompression system can be 0 in a row before aborting */ +#define OFFSET_ZERO_CHECK_TIMES 3 + +BOOT_LOG_MODULE_DECLARE(mcuboot); + +static int boot_sha_protected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, uint32_t protected_size, + uint8_t *buf, size_t buf_size, bootutil_sha_context *sha_ctx); + +bool boot_is_compressed_header_valid(const struct image_header *hdr, const struct flash_area *fap, + struct boot_loader_state *state) +{ + /* Image is compressed in secondary slot, need to check if fits into the primary slot */ + bool opened_flash_area = false; + int primary_fa_id; + int rc; + int size_check; + int size; + uint32_t protected_tlvs_size; + uint32_t decompressed_size; + + if (BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT) == NULL) { + opened_flash_area = true; + } + + primary_fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT); + rc = flash_area_open(primary_fa_id, &BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); + assert(rc == 0); + + size_check = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); + + if (opened_flash_area) { + (void)flash_area_close(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); + } + + rc = bootutil_get_img_decomp_size(hdr, fap, &decompressed_size); + + if (rc) { + return false; + } + + if (!boot_u32_safe_add(&size, decompressed_size, hdr->ih_hdr_size)) { + return false; + } + + rc = boot_size_protected_tlvs(hdr, fap, &protected_tlvs_size); + + if (rc) { + return false; + } + + if (!boot_u32_safe_add(&size, size, protected_tlvs_size)) { + return false; + } + + if (size >= size_check) { + BOOT_LOG_ERR("Compressed image too large, decompressed image size: 0x%x, slot size: 0x%x", + size, size_check); + + return false; + } + + return true; +} + +int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index, + struct image_header *hdr, const struct flash_area *fap, + uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result, + uint8_t *seed, int seed_len) +{ + int rc; + uint32_t read_pos = 0; + uint32_t write_pos = 0; + uint32_t protected_tlv_size = 0; + uint32_t decompressed_image_size; + struct nrf_compress_implementation *compression = NULL; + TARGET_STATIC struct image_header modified_hdr; + bootutil_sha_context sha_ctx; + uint8_t flash_erased_value; + + bootutil_sha_init(&sha_ctx); + + /* Setup decompression system */ +#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) { +#elif CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) { +#endif + /* Compressed image does not use the correct compression type which is supported by this + * build + */ + BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); + rc = BOOT_EBADIMAGE; + + goto finish_without_clean; + } + + compression = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + if (compression == NULL || compression->init == NULL || compression->deinit == NULL || + compression->decompress_bytes_needed == NULL || compression->decompress == NULL) { + /* Compression library missing or missing required function pointer */ + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + + goto finish_without_clean; + } + + rc = compression->init(NULL); + + if (rc) { + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + + goto finish_without_clean; + } + + /* We need a modified header which has the updated sizes, start with the original header */ + memcpy(&modified_hdr, hdr, sizeof(modified_hdr)); + + /* Extract the decompressed image size from the protected TLV, set it and remove the + * compressed image flags + */ + rc = bootutil_get_img_decomp_size(hdr, fap, &decompressed_image_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + modified_hdr.ih_flags &= ~COMPRESSIONFLAGS; + modified_hdr.ih_img_size = decompressed_image_size; + + /* Calculate the protected TLV size, these will not include the decompressed + * sha/size/signature entries + */ + rc = boot_size_protected_tlvs(hdr, fap, &protected_tlv_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + modified_hdr.ih_protect_tlv_size = protected_tlv_size; + bootutil_sha_update(&sha_ctx, &modified_hdr, sizeof(modified_hdr)); + read_pos = sizeof(modified_hdr); + flash_erased_value = flash_area_erased_val(fap); + memset(tmp_buf, flash_erased_value, tmp_buf_sz); + + while (read_pos < modified_hdr.ih_hdr_size) { + uint32_t copy_size = tmp_buf_sz; + + if ((read_pos + copy_size) > modified_hdr.ih_hdr_size) { + copy_size = modified_hdr.ih_hdr_size - read_pos; + } + + bootutil_sha_update(&sha_ctx, tmp_buf, copy_size); + read_pos += copy_size; + } + + /* Read in compressed data, decompress and add to hash calculation */ + read_pos = 0; + + while (read_pos < hdr->ih_img_size) { + uint32_t copy_size = hdr->ih_img_size - read_pos; + uint32_t tmp_off = 0; + uint8_t offset_zero_check = 0; + + if (copy_size > tmp_buf_sz) { + copy_size = tmp_buf_sz; + } + + rc = flash_area_read(fap, (hdr->ih_hdr_size + read_pos), tmp_buf, copy_size); + + if (rc != 0) { + BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (hdr->ih_hdr_size + read_pos), copy_size, fap->fa_id, rc); + rc = BOOT_EFLASH; + + goto finish; + } + + /* Decompress data in chunks, writing it back with a larger write offset of the primary + * slot than read size of the secondary slot + */ + while (tmp_off < copy_size) { + uint32_t offset = 0; + uint8_t *output = NULL; + uint32_t output_size = 0; + uint32_t chunk_size; + bool last_packet = false; + + chunk_size = compression->decompress_bytes_needed(NULL); + + if (chunk_size > (copy_size - tmp_off)) { + chunk_size = (copy_size - tmp_off); + } + + if ((read_pos + tmp_off + chunk_size) >= hdr->ih_img_size) { + last_packet = true; + } + + rc = compression->decompress(NULL, &tmp_buf[tmp_off], chunk_size, last_packet, &offset, + &output, &output_size); + + if (rc) { + BOOT_LOG_ERR("Decompression error: %d", rc); + rc = BOOT_EBADSTATUS; + + goto finish; + } + + write_pos += output_size; + + if (write_pos > decompressed_image_size) { + BOOT_LOG_ERR("Decompressed image larger than claimed TLV size, at least: %d", + write_pos); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + /* Additional dry-run validity checks */ + if (last_packet == true && write_pos == 0) { + /* Last packet and we still have no output, this is a faulty update */ + BOOT_LOG_ERR("All compressed data consumed without any output, image not valid"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + if (offset == 0) { + /* If the decompression system continually consumes 0 bytes, then there is a + * problem with this update image, abort and mark image as bad + */ + if (offset_zero_check >= OFFSET_ZERO_CHECK_TIMES) { + BOOT_LOG_ERR("Decompression system returning no output data, image not valid"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + ++offset_zero_check; + + break; + } else { + offset_zero_check = 0; + } + + if (output_size > 0) { + bootutil_sha_update(&sha_ctx, output, output_size); + } + + tmp_off += offset; + } + + read_pos += copy_size; + } + + /* If there are any protected TLVs present, add them after the main decompressed image */ + if (modified_hdr.ih_protect_tlv_size > 0) { + rc = boot_sha_protected_tlvs(hdr, fap, modified_hdr.ih_protect_tlv_size, tmp_buf, + tmp_buf_sz, &sha_ctx); + } + + bootutil_sha_finish(&sha_ctx, hash_result); + +finish: + /* Clean up decompression system */ + (void)compression->deinit(NULL); + +finish_without_clean: + bootutil_sha_drop(&sha_ctx); + + return rc; +} + +static int boot_copy_protected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_dst, + uint32_t protected_size, uint8_t *buf, size_t buf_size, + uint16_t *buf_pos, uint32_t *written) +{ + int rc; + uint32_t off; + uint32_t write_pos = 0; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + struct image_tlv tlv_header; + struct image_tlv_info tlv_info_header = { + .it_magic = IMAGE_TLV_PROT_INFO_MAGIC, + .it_tlv_tot = protected_size, + }; + uint16_t info_size_left = sizeof(tlv_info_header); + + while (info_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + + if (info_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + uint8_t *tlv_info_header_address = (uint8_t *)&tlv_info_header; + + if (single_copy_size > info_size_left) { + single_copy_size = info_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_info_header_address[sizeof(tlv_info_header) - + info_size_left], single_copy_size); + *buf_pos += single_copy_size; + info_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, true); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || + type == IMAGE_TLV_DECOMP_SIGNATURE) { + /* Skip these TLVs as they are not needed */ + continue; + } else { + uint16_t header_size_left = sizeof(tlv_header); + uint16_t data_size_left = len; + + tlv_header.it_type = type; + tlv_header.it_len = len; + + while (header_size_left > 0 || data_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + uint8_t *tlv_header_address = (uint8_t *)&tlv_header; + + if (header_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + + if (single_copy_size > header_size_left) { + single_copy_size = header_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_header_address[sizeof(tlv_header) - + header_size_left], + single_copy_size); + *buf_pos += single_copy_size; + copy_size -= single_copy_size; + header_size_left -= single_copy_size; + } + + if (data_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + + if (single_copy_size > data_size_left) { + single_copy_size = data_size_left; + } + + rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + (len - data_size_left)), + &buf[*buf_pos], single_copy_size); + + if (rc) { + BOOT_LOG_ERR( + "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); + + goto out; + } + + *buf_pos += single_copy_size; + data_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR( + "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + } + } + + *written = write_pos; + +out: + return rc; +} + +static int boot_sha_protected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, uint32_t protected_size, + uint8_t *buf, size_t buf_size, bootutil_sha_context *sha_ctx) +{ + int rc; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + struct image_tlv tlv_header; + struct image_tlv_info tlv_info_header = { + .it_magic = IMAGE_TLV_PROT_INFO_MAGIC, + .it_tlv_tot = protected_size, + }; + + bootutil_sha_update(sha_ctx, &tlv_info_header, sizeof(tlv_info_header)); + + rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, true); + if (rc) { + goto out; + } + + while (true) { + uint32_t read_off = 0; + + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || + type == IMAGE_TLV_DECOMP_SIGNATURE) { + /* Skip these TLVs as they are not needed */ + continue; + } + + tlv_header.it_type = type; + tlv_header.it_len = len; + + bootutil_sha_update(sha_ctx, &tlv_header, sizeof(tlv_header)); + + while (read_off < len) { + uint32_t copy_size = buf_size; + + if (copy_size > (len - read_off)) { + copy_size = len - read_off; + } + + rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + read_off), buf, copy_size); + + if (rc) { + BOOT_LOG_ERR( + "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off + read_off), copy_size, fap_src->fa_id, rc); + + goto out; + } + + bootutil_sha_update(sha_ctx, buf, copy_size); + read_off += copy_size; + } + } + +out: + return rc; +} + +int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *sz) +{ + int rc = 0; + uint32_t tlv_size; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + + *sz = 0; + tlv_size = hdr->ih_protect_tlv_size; + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, true); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || + type == IMAGE_TLV_DECOMP_SIGNATURE) { + /* Exclude these TLVs as they will be copied to the unprotected area */ + tlv_size -= len + sizeof(struct image_tlv); + } + } + + if (!rc) { + if (tlv_size == sizeof(struct image_tlv_info)) { + /* If there are no entries then omit protected TLV section entirely */ + tlv_size = 0; + } + + *sz = tlv_size; + } + +out: + return rc; +} + +int boot_size_unprotected_tlvs(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *sz) +{ + int rc = 0; + uint32_t tlv_size; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + + *sz = 0; + tlv_size = sizeof(struct image_tlv_info); + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } else if (bootutil_tlv_iter_is_prot(&it, off)) { + continue; + } + + tlv_size += len + sizeof(struct image_tlv); + } + + if (!rc) { + if (tlv_size == sizeof(struct image_tlv_info)) { + /* If there are no entries in the unprotected TLV section then there is something wrong + * with this image + */ + BOOT_LOG_ERR("No unprotected TLVs in post-decompressed image output, image is invalid"); + rc = BOOT_EBADIMAGE; + + goto out; + } + + *sz = tlv_size; + } + +out: + return rc; +} + +static int boot_copy_unprotected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_dst, + uint32_t unprotected_size, uint8_t *buf, size_t buf_size, + uint16_t *buf_pos, uint32_t *written) +{ + int rc; + uint32_t write_pos = 0; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + struct image_tlv_iter it_protected; + struct image_tlv tlv_header; + struct image_tlv_info tlv_info_header = { + .it_magic = IMAGE_TLV_INFO_MAGIC, + .it_tlv_tot = unprotected_size, + }; + uint16_t info_size_left = sizeof(tlv_info_header); + + while (info_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + + if (info_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + uint8_t *tlv_info_header_address = (uint8_t *)&tlv_info_header; + + if (single_copy_size > info_size_left) { + single_copy_size = info_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_info_header_address[sizeof(tlv_info_header) - + info_size_left], single_copy_size); + *buf_pos += single_copy_size; + info_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, false); + if (rc) { + goto out; + } + + while (true) { + uint16_t header_size_left = sizeof(tlv_header); + uint16_t data_size_left; + + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } else if (bootutil_tlv_iter_is_prot(&it, off)) { + /* Skip protected TLVs */ + continue; + } + + /* Change the values of these fields from having the data in the compressed image + * unprotected TLV (which is valid only for the compressed image data) to having the + * fields in the protected TLV section (which is valid for the decompressed image data). + * The compressed data is no longer needed + */ + if (type == EXPECTED_HASH_TLV || type == EXPECTED_SIG_TLV) { + rc = bootutil_tlv_iter_begin(&it_protected, hdr, fap_src, (type == EXPECTED_HASH_TLV ? + IMAGE_TLV_DECOMP_SHA : + IMAGE_TLV_DECOMP_SIGNATURE), + true); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it_protected, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + } + + if (type == IMAGE_TLV_DECOMP_SHA) { + type = EXPECTED_HASH_TLV; + } else { + type = EXPECTED_SIG_TLV; + } + } + + data_size_left = len; + tlv_header.it_type = type; + tlv_header.it_len = len; + + while (header_size_left > 0 || data_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + + if (header_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + uint8_t *tlv_header_address = (uint8_t *)&tlv_header; + + if (single_copy_size > header_size_left) { + single_copy_size = header_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_header_address[sizeof(tlv_header) - header_size_left], + single_copy_size); + *buf_pos += single_copy_size; + copy_size -= single_copy_size; + header_size_left -= single_copy_size; + } + + if (data_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + + if (single_copy_size > data_size_left) { + single_copy_size = data_size_left; + } + + rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + len - data_size_left), + &buf[*buf_pos], single_copy_size); + + if (rc) { + BOOT_LOG_ERR( + "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); + + goto out; + } + + *buf_pos += single_copy_size; + data_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR( + "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + } + + *written = write_pos; + +out: + return rc; +} + +int boot_copy_region_decompress(struct boot_loader_state *state, const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_src, + uint32_t off_dst, uint32_t sz, uint8_t *buf, size_t buf_size) +{ + int rc; + uint32_t pos = 0; + uint16_t decomp_buf_size = 0; + uint16_t write_alignment; + uint32_t write_pos = 0; + uint32_t protected_tlv_size = 0; + uint32_t unprotected_tlv_size = 0; + uint32_t tlv_write_size = 0; + uint32_t decompressed_image_size; + struct nrf_compress_implementation *compression = NULL; + struct image_header *hdr; + TARGET_STATIC uint8_t decomp_buf[CONFIG_BOOT_DECOMPRESSION_BUFFER_SIZE] __attribute__((aligned(4))); + TARGET_STATIC struct image_header modified_hdr; + + hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + + /* Setup decompression system */ +#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) { +#elif CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) { +#endif + /* Compressed image does not use the correct compression type which is supported by this + * build + */ + BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + compression = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + if (compression == NULL || compression->init == NULL || compression->deinit == NULL || + compression->decompress_bytes_needed == NULL || compression->decompress == NULL) { + /* Compression library missing or missing required function pointer */ + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + + goto finish; + } + + rc = compression->init(NULL); + + if (rc) { + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + + goto finish; + } + + write_alignment = flash_area_align(fap_dst); + + memcpy(&modified_hdr, hdr, sizeof(modified_hdr)); + + rc = bootutil_get_img_decomp_size(hdr, fap_src, &decompressed_image_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + modified_hdr.ih_flags &= ~COMPRESSIONFLAGS; + modified_hdr.ih_img_size = decompressed_image_size; + + /* Calculate protected TLV size for target image once items are removed */ + rc = boot_size_protected_tlvs(hdr, fap_src, &protected_tlv_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + modified_hdr.ih_protect_tlv_size = protected_tlv_size; + + rc = boot_size_unprotected_tlvs(hdr, fap_src, &unprotected_tlv_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine unprotected TLV size of compressed image"); + rc = BOOT_EBADIMAGE; + + goto finish; + } + + /* Write out the image header first, this should be a multiple of the write size */ + rc = flash_area_write(fap_dst, off_dst, &modified_hdr, sizeof(modified_hdr)); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + off_dst, sizeof(modified_hdr), fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto finish; + } + + /* Read in, decompress and write out data */ + while (pos < hdr->ih_img_size) { + uint32_t copy_size = hdr->ih_img_size - pos; + uint32_t tmp_off = 0; + + if (copy_size > buf_size) { + copy_size = buf_size; + } + + rc = flash_area_read(fap_src, off_src + hdr->ih_hdr_size + pos, buf, copy_size); + + if (rc != 0) { + BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_src + hdr->ih_hdr_size + pos), copy_size, fap_src->fa_id, rc); + rc = BOOT_EFLASH; + + goto finish; + } + + /* Decompress data in chunks, writing it back with a larger write offset of the primary + * slot than read size of the secondary slot + */ + while (tmp_off < copy_size) { + uint32_t offset = 0; + uint32_t output_size = 0; + uint32_t chunk_size; + uint32_t compression_buffer_pos = 0; + uint8_t *output = NULL; + bool last_packet = false; + + chunk_size = compression->decompress_bytes_needed(NULL); + + if (chunk_size > (copy_size - tmp_off)) { + chunk_size = (copy_size - tmp_off); + } + + if ((pos + tmp_off + chunk_size) >= hdr->ih_img_size) { + last_packet = true; + } + + rc = compression->decompress(NULL, &buf[tmp_off], chunk_size, last_packet, &offset, + &output, &output_size); + + if (rc) { + BOOT_LOG_ERR("Decompression error: %d", rc); + rc = BOOT_EBADSTATUS; + + goto finish; + } + + /* Copy data to secondary buffer for writing out */ + while (output_size > 0) { + uint32_t data_size = (sizeof(decomp_buf) - decomp_buf_size); + + if (data_size > output_size) { + data_size = output_size; + } + + memcpy(&decomp_buf[decomp_buf_size], &output[compression_buffer_pos], data_size); + compression_buffer_pos += data_size; + + decomp_buf_size += data_size; + output_size -= data_size; + + /* Write data out from secondary buffer when it is full */ + if (decomp_buf_size == sizeof(decomp_buf)) { + rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), + decomp_buf, sizeof(decomp_buf)); + + if (rc != 0) { + BOOT_LOG_ERR( + "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + hdr->ih_hdr_size + write_pos), sizeof(decomp_buf), + fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto finish; + } + + write_pos += sizeof(decomp_buf); + decomp_buf_size = 0; + } + } + + tmp_off += offset; + } + + pos += copy_size; + } + + /* Clean up decompression system */ + (void)compression->deinit(NULL); + + if (protected_tlv_size > 0) { + rc = boot_copy_protected_tlvs(hdr, fap_src, fap_dst, (off_dst + hdr->ih_hdr_size + + write_pos), protected_tlv_size, + decomp_buf, sizeof(decomp_buf_size), &decomp_buf_size, + &tlv_write_size); + + if (rc) { + BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); + + goto finish; + } + + write_pos += tlv_write_size; + } + + tlv_write_size = 0; + rc = boot_copy_unprotected_tlvs(hdr, fap_src, fap_dst, (off_dst + hdr->ih_hdr_size + + write_pos), unprotected_tlv_size, + decomp_buf, sizeof(decomp_buf_size), &decomp_buf_size, + &tlv_write_size); + + if (rc) { + BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); + + goto finish; + } + + write_pos += tlv_write_size; + + /* Check if we have unwritten data buffered up and, if so, write it out */ + if (decomp_buf_size > 0) { + uint32_t write_padding_size = decomp_buf_size % write_alignment; + + /* Check if additional write padding should be applied to meet the minimum write size */ + if (write_padding_size) { + uint8_t flash_erased_value; + + flash_erased_value = flash_area_erased_val(fap_dst); + memset(&decomp_buf[decomp_buf_size], flash_erased_value, write_padding_size); + decomp_buf_size += write_padding_size; + } + + rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), decomp_buf, + decomp_buf_size); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + hdr->ih_hdr_size + write_pos), sizeof(decomp_buf_size), + fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + + goto finish; + } + + write_pos += decomp_buf_size; + decomp_buf_size = 0; + } + +finish: + memset(decomp_buf, 0, sizeof(decomp_buf)); + + return rc; +} + +int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *img_decomp_size) +{ + struct image_tlv_iter it; + uint32_t off; + uint16_t len; + int32_t rc; + + if (hdr == NULL || fap == NULL || img_decomp_size == NULL) { + return BOOT_EBADARGS; + } else if (hdr->ih_protect_tlv_size == 0) { + return BOOT_EBADIMAGE; + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIZE, true); + + if (rc) { + return rc; + } + + rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); + + if (rc != 0) { + return -1; + } + + if (len != sizeof(*img_decomp_size)) { + BOOT_LOG_ERR("Invalid decompressed image size TLV: %d", len); + + return BOOT_EBADIMAGE; + } + + rc = LOAD_IMAGE_DATA(hdr, fap, off, img_decomp_size, len); + + if (rc) { + BOOT_LOG_ERR("Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + off, len, fap->fa_id, rc); + + return BOOT_EFLASH; + } + + return 0; +} diff --git a/boot/zephyr/include/compression/decompression.h b/boot/zephyr/include/compression/decompression.h new file mode 100644 index 000000000..f8a676ac5 --- /dev/null +++ b/boot/zephyr/include/compression/decompression.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef H_DECOMPRESSION_ +#define H_DECOMPRESSION_ + +#include +#include +#include +#include "bootutil/bootutil.h" +#include "bootutil/bootutil_public.h" +#include "bootutil/image.h" +#include "../src/bootutil_priv.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Checks if a compressed image header is valid. + * + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param state Bootloader state object. + * + * @return true if valid; false if invalid. + */ +bool boot_is_compressed_header_valid(const struct image_header *hdr, const struct flash_area *fap, + struct boot_loader_state *state); + +/** + * Reads in compressed image data from a slot, decompresses it and writes it out to a destination + * slot, including corresponding image headers and TLVs. + * + * @param state Bootloader state object. + * @param fap_src Flash area of the source slot. + * @param fap_dst Flash area of the destination slot. + * @param off_src Offset of the source slot to read from (should be 0). + * @param off_dst Offset of the destination slot to write to (should be 0). + * @param sz Size of the source slot data. + * @param buf Temporary buffer for reading data from. + * @param buf_size Size of temporary buffer. + * + * @return 0 on success; nonzero on failure. + */ +int boot_copy_region_decompress(struct boot_loader_state *state, const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_src, + uint32_t off_dst, uint32_t sz, uint8_t *buf, size_t buf_size); + +/** + * Gets the total data size (excluding headers and TLVs) of a compressed image when it is + * decompressed. + * + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param img_decomp_size Pointer to variable that will be updated with the decompressed image + * size. + * + * @return 0 on success; nonzero on failure. + */ +int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *img_decomp_size); + +/** + * Calculate MCUboot-compatible image hash of compressed image slot. + * + * @param enc_state Not currently used, set to NULL. + * @param image_index Image number. + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param tmp_buf Temporary buffer for reading data from. + * @param tmp_buf_sz Size of temporary buffer. + * @param hash_result Pointer to a variable that will be updated with the image hash. + * @param seed Not currently used, set to NULL. + * @param seed_len Not currently used, set to 0. + * + * @return 0 on success; nonzero on failure. + */ +int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index, + struct image_header *hdr, const struct flash_area *fap, + uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result, + uint8_t *seed, int seed_len); + +/** + * Calculates the size that the compressed image protected TLV section will occupy once the image + * has been decompressed. + * + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param sz Pointer to variable that will be updated with the protected TLV size. + * + * @return 0 on success; nonzero on failure. + */ +int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_area *fap_src, + uint32_t *sz); + +#ifdef __cplusplus +} +#endif + +#endif /* H_DECOMPRESSION_ */ From 756c5bf1bc19427e5c7901440c5a8f774e1decc8 Mon Sep 17 00:00:00 2001 From: Mateusz Michalek Date: Mon, 20 May 2024 08:47:02 +0200 Subject: [PATCH 212/238] [nrf fromtree] boot: SHA512 verification adds TLV and Kconfig to decouple verification from other options. Signed-off-by: Mateusz Michalek Signed-off-by: Dominik Ermel (cherry picked from commit 41df52e6906172ed3398b1478e4809abfc2bc3e2) --- boot/bootutil/include/bootutil/crypto/sha.h | 15 +++-- boot/bootutil/include/bootutil/image.h | 1 + boot/bootutil/src/image_validate.c | 1 + boot/zephyr/Kconfig | 56 +++++++++++++++++++ .../include/mcuboot_config/mcuboot_config.h | 10 ++++ 5 files changed, 79 insertions(+), 4 deletions(-) diff --git a/boot/bootutil/include/bootutil/crypto/sha.h b/boot/bootutil/include/bootutil/crypto/sha.h index 9ce54bee5..28499ed6a 100644 --- a/boot/bootutil/include/bootutil/crypto/sha.h +++ b/boot/bootutil/include/bootutil/crypto/sha.h @@ -34,13 +34,16 @@ #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO" #endif -#if defined(MCUBOOT_SIGN_EC384) +#if defined(MCUBOOT_SHA512) + #define IMAGE_HASH_SIZE (64) + #define EXPECTED_HASH_TLV IMAGE_TLV_SHA512 +#elif defined(MCUBOOT_SIGN_EC384) #define IMAGE_HASH_SIZE (48) #define EXPECTED_HASH_TLV IMAGE_TLV_SHA384 #else #define IMAGE_HASH_SIZE (32) #define EXPECTED_HASH_TLV IMAGE_TLV_SHA256 -#endif /* MCUBOOT_SIGN_EC384 */ +#endif /* MCUBOOT_SIGN */ /* Universal defines for SHA-256 */ #define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64) @@ -82,7 +85,9 @@ typedef psa_hash_operation_t bootutil_sha_context; static inline int bootutil_sha_init(bootutil_sha_context *ctx) { *ctx = psa_hash_operation_init(); -#if defined(MCUBOOT_SIGN_EC384) +#if defined(MCUBOOT_SHA512) + psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_512); +#elif defined(MCUBOOT_SIGN_EC384) psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_384); #else psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_256); @@ -107,7 +112,9 @@ static inline int bootutil_sha_finish(bootutil_sha_context *ctx, { size_t hash_length = 0; /* Assumes the output buffer is at least the expected size of the hash */ -#if defined(MCUBOOT_SIGN_EC384) +#if defined(MCUBOOT_SHA512) + return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_512), &hash_length); +#elif defined(MCUBOOT_SIGN_EC384) return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_384), &hash_length); #else return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_256), &hash_length); diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 3e03f80dd..9ede800a2 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -96,6 +96,7 @@ struct flash_area; #define IMAGE_TLV_PUBKEY 0x02 /* public key */ #define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */ #define IMAGE_TLV_SHA384 0x11 /* SHA384 of image hdr and body */ +#define IMAGE_TLV_SHA512 0x12 /* SHA512 of image hdr and body */ #define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */ #define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output - Not supported anymore */ #define IMAGE_TLV_ECDSA_SIG 0x22 /* ECDSA of hash output */ diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 1811cdb87..4db434d6e 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -371,6 +371,7 @@ static const uint16_t allowed_unprot_tlvs[] = { IMAGE_TLV_PUBKEY, IMAGE_TLV_SHA256, IMAGE_TLV_SHA384, + IMAGE_TLV_SHA512, IMAGE_TLV_RSA2048_PSS, IMAGE_TLV_ECDSA224, IMAGE_TLV_ECDSA_SIG, diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 6fe786c07..de841ddc1 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -27,6 +27,12 @@ config BOOT_USE_MBEDTLS help Use mbedTLS for crypto primitives. +config BOOT_USE_PSA_CRYPTO + bool + # Hidden option + help + Hidden option set if using PSA crypt for cryptography functionality + config BOOT_USE_TINYCRYPT bool # Hidden option @@ -70,6 +76,52 @@ config SINGLE_APPLICATION_SLOT uploading a new application overwrites the one that previously occupied the area. +config BOOT_IMG_HASH_ALG_SHA256_ALLOW + bool + help + Hidden option set by configurations that allow SHA256 + +config BOOT_IMG_HASH_ALG_SHA384_ALLOW + bool + help + Hidden option set by configurations that allow SHA384 + +config BOOT_IMG_HASH_ALG_SHA512_ALLOW + bool + depends on BOOT_USE_PSA_CRYPTO + help + Hidden option set by configurations that allow SHA512 + +choice BOOT_IMG_HASH_ALG + prompt "Selected image hash algorithm" + default BOOT_IMG_HASH_ALG_SHA256 if BOOT_IMG_HASH_ALG_SHA256_ALLOW + default BOOT_IMG_HASH_ALG_SHA384 if BOOT_IMG_HASH_ALG_SHA384_ALLOW + default BOOT_IMG_HASH_ALG_SHA512 if BOOT_IMG_HASH_ALG_SHA512_ALLOW + help + Hash algorithm used for image verification. Selection + here may be limited by other configurations, like for + example selected cryptographic signature. + +config BOOT_IMG_HASH_ALG_SHA256 + bool "SHA256" + depends on BOOT_IMG_HASH_ALG_SHA256_ALLOW + help + SHA256 algorithm + +config BOOT_IMG_HASH_ALG_SHA384 + bool "SHA384" + depends on BOOT_IMG_HASH_ALG_SHA384_ALLOW + help + SHA384 algorithm + +config BOOT_IMG_HASH_ALG_SHA512 + bool "SHA512" + depends on BOOT_IMG_HASH_ALG_SHA512_ALLOW + help + SHA512 algorithm + +endchoice # BOOT_IMG_HASH_ALG + choice BOOT_SIGNATURE_TYPE prompt "Signature type" default BOOT_SIGNATURE_TYPE_RSA @@ -77,12 +129,14 @@ choice BOOT_SIGNATURE_TYPE config BOOT_SIGNATURE_TYPE_NONE bool "No signature; use only hash check" select BOOT_USE_TINYCRYPT + select BOOT_IMG_HASH_ALG_SHA256_ALLOW config BOOT_SIGNATURE_TYPE_RSA bool "RSA signatures" select BOOT_USE_MBEDTLS select MBEDTLS select BOOT_ENCRYPTION_SUPPORT + select BOOT_IMG_HASH_ALG_SHA256_ALLOW if BOOT_SIGNATURE_TYPE_RSA config BOOT_SIGNATURE_TYPE_RSA_LEN @@ -94,6 +148,7 @@ endif config BOOT_SIGNATURE_TYPE_ECDSA_P256 bool "Elliptic curve digital signatures with curve P-256" select BOOT_ENCRYPTION_SUPPORT + select BOOT_IMG_HASH_ALG_SHA256_ALLOW if BOOT_SIGNATURE_TYPE_ECDSA_P256 choice BOOT_ECDSA_IMPLEMENTATION @@ -117,6 +172,7 @@ endif config BOOT_SIGNATURE_TYPE_ED25519 bool "Edwards curve digital signatures using ed25519" select BOOT_ENCRYPTION_SUPPORT + select BOOT_IMG_HASH_ALG_SHA256_ALLOW if BOOT_SIGNATURE_TYPE_ED25519 choice BOOT_ED25519_IMPLEMENTATION diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 0891a4b11..56462fb76 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -43,6 +43,16 @@ #ifdef CONFIG_BOOT_USE_NRF_CC310_BL #define MCUBOOT_USE_NRF_CC310_BL #endif +#elif defined(CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT) +#define MCUBOOT_USE_PSA_CRYPTO +#endif + +#ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA512 +#define MCUBOOT_SHA512 +#endif + +#ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA256 +#define MCUBOOT_SHA256 #endif /* Zephyr, regardless of C library used, provides snprintf */ From 4e0dee6f1f656d682ee9e9f92d146e64cf8cce04 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Thu, 14 Feb 2019 13:20:34 +0100 Subject: [PATCH 213/238] [nrf noup] boot: Add shared crypto for ECDSA and SHA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add functions for ecdsa_verify_secp256r1 and sha256 to use the shared crypto API * Add Kconfig and CMake variables for selecting shared crypto when using ecdsa * Add custom section to project for placing the API section in the correct location in flash * Add kconfig fragment for using external crypto Signed-off-by: Sigvart Hovland Signed-off-by: Martí Bolívar Signed-off-by: Emil Obalski Signed-off-by: Andrzej Puzdrowski Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Trond Einar Snekvik Signed-off-by: Georgios Vasilakis Signed-off-by: Johann Fischer Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 55683e3133b6a801a7bb7feb55d24be81ecccdbb) (cherry picked from commit 0faa8b2bb51bd58c9a1d3470f78f7b4136999652) (cherry picked from commit a42e9cc5fa46b614e60353d6a255984f72ab4d7e) (cherry picked from commit 895c76beb540d91cd9ddb53198bbfde0089c36d4) (cherry picked from commit ff5338297c4be31e757f99d8cf5730b05a5cbed6) (cherry picked from commit cc42516352e797433e6e0413fc41e08d2b583739) --- boot/bootutil/include/bootutil/crypto/ecdsa.h | 64 +++++++++++++++++-- boot/bootutil/include/bootutil/crypto/sha.h | 32 ++++++++++ boot/zephyr/CMakeLists.txt | 2 + boot/zephyr/external_crypto.conf | 20 ++++++ .../include/mcuboot_config/mcuboot_config.h | 5 +- 5 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 boot/zephyr/external_crypto.conf diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index 3b0541072..85355f20c 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -34,6 +34,7 @@ #if (defined(MCUBOOT_USE_TINYCRYPT) + \ defined(MCUBOOT_USE_CC310) + \ + defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_PSA_OR_MBED_TLS)) != 1 #error "One crypto backend must be defined: either CC310/TINYCRYPT/MBED_TLS/PSA_CRYPTO" #endif @@ -70,12 +71,18 @@ #include "bootutil/sign_key.h" #include "common.h" +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + #include + #define NUM_ECC_BYTES (256 / 8) +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus extern "C" { #endif #if (defined(MCUBOOT_USE_TINYCRYPT) || defined(MCUBOOT_USE_MBED_TLS) || \ - defined(MCUBOOT_USE_CC310)) && !defined(MCUBOOT_USE_PSA_CRYPTO) + defined(MCUBOOT_USE_CC310) || defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO)) \ + && !defined(MCUBOOT_USE_PSA_CRYPTO) /* * Declaring these like this adds NULL termination. */ @@ -127,8 +134,6 @@ static int bootutil_import_key(uint8_t **cp, uint8_t *end) } #endif /* (MCUBOOT_USE_TINYCRYPT || MCUBOOT_USE_MBED_TLS || MCUBOOT_USE_CC310) && !MCUBOOT_USE_PSA_CRYPTO */ -#if defined(MCUBOOT_USE_TINYCRYPT) -#ifndef MCUBOOT_ECDSA_NEED_ASN1_SIG /* * cp points to ASN1 string containing an integer. * Verify the tag, and that the length is 32 bytes. Helper function. @@ -178,8 +183,8 @@ static int bootutil_decode_sig(uint8_t signature[NUM_ECC_BYTES * 2], uint8_t *cp } return 0; } -#endif /* not MCUBOOT_ECDSA_NEED_ASN1_SIG */ +#if defined(MCUBOOT_USE_TINYCRYPT) typedef uintptr_t bootutil_ecdsa_context; static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) { @@ -248,8 +253,12 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, { (void)ctx; (void)pk_len; - (void)sig_len; (void)hash_len; + uint8_t dsig[2 * NUM_ECC_BYTES]; + + if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { + return -1; + } /* Only support uncompressed keys. */ if (pk[0] != 0x04) { @@ -257,7 +266,7 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, } pk++; - return cc310_ecdsa_verify_secp256r1(hash, pk, sig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); + return cc310_ecdsa_verify_secp256r1(hash, pk, dsig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); } static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, @@ -613,6 +622,49 @@ static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, #endif /* MCUBOOT_USE_MBED_TLS */ +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) +typedef uintptr_t bootutil_ecdsa_context; +static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) +{ + (void)ctx; +} + +static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx) +{ + (void)ctx; +} + +static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, + uint8_t *pk, size_t pk_len, + uint8_t *hash, size_t hash_len, + uint8_t *sig, size_t sig_len) +{ + (void)ctx; + (void)pk_len; + (void)hash_len; + uint8_t dsig[2 * NUM_ECC_BYTES]; + + if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { + return -1; + } + + /* Only support uncompressed keys. */ + if (pk[0] != 0x04) { + return -1; + } + pk++; + + return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, pk, dsig); +} + +static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, + uint8_t **cp,uint8_t *end) +{ + (void)ctx; + return bootutil_import_key(cp, end); +} +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus } #endif diff --git a/boot/bootutil/include/bootutil/crypto/sha.h b/boot/bootutil/include/bootutil/crypto/sha.h index 28499ed6a..aeedff40e 100644 --- a/boot/bootutil/include/bootutil/crypto/sha.h +++ b/boot/bootutil/include/bootutil/crypto/sha.h @@ -30,6 +30,7 @@ #if (defined(MCUBOOT_USE_PSA_OR_MBED_TLS) + \ defined(MCUBOOT_USE_TINYCRYPT) + \ + defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_CC310)) != 1 #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO" #endif @@ -213,6 +214,37 @@ static inline int bootutil_sha_finish(bootutil_sha_context *ctx, } #endif /* MCUBOOT_USE_CC310 */ +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + +#include + +typedef bl_sha256_ctx_t bootutil_sha_context; + +static inline void bootutil_sha_init(bootutil_sha_context *ctx) +{ + bl_sha256_init(ctx); +} + +static inline void bootutil_sha_drop(bootutil_sha_context *ctx) +{ + (void)ctx; +} + +static inline int bootutil_sha_update(bootutil_sha_context *ctx, + const void *data, + uint32_t data_len) +{ + return bl_sha256_update(ctx, data, data_len); +} + +static inline int bootutil_sha_finish(bootutil_sha_context *ctx, + uint8_t *output) +{ + bl_sha256_finalize(ctx, output); + return 0; +} +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus } #endif diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 253ab2537..c0a0f0dbe 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -171,6 +171,8 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) zephyr_library_sources(${MCUBOOT_NRF_EXT_DIR}/cc310_glue.c) zephyr_library_include_directories(${MCUBOOT_NRF_EXT_DIR}) zephyr_link_libraries(nrfxlib_crypto) + elseif(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) + zephyr_include_directories(${BL_CRYPTO_DIR}/../include) endif() # Since here we are not using Zephyr's mbedTLS but rather our own, we need diff --git a/boot/zephyr/external_crypto.conf b/boot/zephyr/external_crypto.conf new file mode 100644 index 000000000..8181ad51c --- /dev/null +++ b/boot/zephyr/external_crypto.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# These configurations should be used when using nrf/samples/bootloader +# as the immutable bootloader (B0), and MCUBoot as the second stage updateable +# bootloader. + +# Set ECDSA as signing mechanism +CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y + +# Use crypto backend from B0 +CONFIG_BOOT_NRF_EXTERNAL_CRYPTO=y +CONFIG_SECURE_BOOT_CRYPTO=y +CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y +CONFIG_SB_CRYPTO_CLIENT_SHA256=y +CONFIG_BL_SHA256_EXT_API_REQUIRED=y +CONFIG_BL_SECP256R1_EXT_API_REQUIRED=y diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 56462fb76..f628f99c4 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -40,11 +40,10 @@ #define MCUBOOT_USE_TINYCRYPT #elif defined(CONFIG_BOOT_USE_CC310) #define MCUBOOT_USE_CC310 -#ifdef CONFIG_BOOT_USE_NRF_CC310_BL -#define MCUBOOT_USE_NRF_CC310_BL -#endif #elif defined(CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT) #define MCUBOOT_USE_PSA_CRYPTO +#elif defined(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) +#define MCUBOOT_USE_NRF_EXTERNAL_CRYPTO #endif #ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA512 From 3a28585c5a5221b487dfd90604f613296172c8af Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 22 Aug 2024 14:58:15 +0000 Subject: [PATCH 214/238] [nrf fromlist] imgtool: Add support for calculating SHA512 The adds support for hashing image with SHA512, to allow SHA512-ED25519-SHA512 signature. To support above --sha parameter has been added that can take value: auto, 256, 384, 512 to select sha, where auto brings the default behaviour, or current, behaviour. The sha provided here is tested against key so not all combinations are supported. Upstream PR: https://github.com/mcu-tools/mcuboot/pull/2048 Signed-off-by: Dominik Ermel --- scripts/imgtool/image.py | 111 ++++++++++++++++++++++++++++++++------- scripts/imgtool/main.py | 8 ++- 2 files changed, 97 insertions(+), 22 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index 5c4732b53..53b19ef1d 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -40,6 +40,8 @@ from .boot_record import create_sw_component_data from .keys import rsa, ecdsa, x25519 +from collections import namedtuple + IMAGE_MAGIC = 0x96f3b83d IMAGE_HEADER_SIZE = 32 BIN_EXT = "bin" @@ -65,6 +67,7 @@ 'PUBKEY': 0x02, 'SHA256': 0x10, 'SHA384': 0x11, + 'SHA512': 0x12, 'RSA2048': 0x20, 'ECDSASIG': 0x22, 'RSA3072': 0x23, @@ -135,11 +138,73 @@ def get(self): return header + bytes(self.buf) +SHAAndAlgT = namedtuple('SHAAndAlgT', ['sha', 'alg']) + +TLV_SHA_TO_SHA_AND_ALG = { + TLV_VALUES['SHA256'] : SHAAndAlgT('256', hashlib.sha256), + TLV_VALUES['SHA384'] : SHAAndAlgT('384', hashlib.sha384), + TLV_VALUES['SHA512'] : SHAAndAlgT('512', hashlib.sha512), +} + + +USER_SHA_TO_ALG_AND_TLV = { + 'auto' : (hashlib.sha256, 'SHA256'), + '256' : (hashlib.sha256, 'SHA256'), + '384' : (hashlib.sha384, 'SHA384'), + '512' : (hashlib.sha512, 'SHA512') +} + + +def is_sha_tlv(tlv): + return tlv in TLV_SHA_TO_SHA_AND_ALG.keys() + + +def tlv_sha_to_sha(tlv): + return TLV_SHA_TO_SHA_AND_ALG[tlv].sha + + +# Auto selecting hash algorithm for type(key) +ALLOWED_KEY_SHA = { + keys.ECDSA384P1 : ['384'], + keys.ECDSA384P1Public : ['384'], + keys.ECDSA256P1 : ['256'], + keys.RSA : ['256'], + # This two are set to 256 for compatibility, the right would be 512 + keys.Ed25519 : ['256', '512'], + keys.X25519 : ['256', '512'] +} + +def key_and_user_sha_to_alg_and_tlv(key, user_sha): + """Matches key and user requested sha to sha alogrithm and TLV name. + + The returned tuple will contain hash functions and TVL name. + The function is designed to succeed or completely fail execution, + as providing incorrect pair here basically prevents doing + any more work. + """ + if key is None: + # If key is none, we allow whatever user has selected for sha + return USER_SHA_TO_ALG_AND_TLV[user_sha] + + # If key is not None, then we have to filter hash to only allowed + allowed = None + try: + allowed = ALLOWED_KEY_SHA[type(key)] + except KeyError: + raise click.UsageError("Colud not find allowed hash algorithms for {}" + .format(type(key))) + if user_sha == 'auto': + return USER_SHA_TO_ALG_AND_TLV[allowed[0]] + + if user_sha in allowed: + return USER_SHA_TO_ALG_AND_TLV[user_sha] + + raise click.UsageError("Key {} can not be used with --sha {}; allowed sha are one of {}" + .format(key.sig_type(), user_sha, allowed)) + + def get_digest(tlv_type, hash_region): - if tlv_type == TLV_VALUES["SHA384"]: - sha = hashlib.sha384() - elif tlv_type == TLV_VALUES["SHA256"]: - sha = hashlib.sha256() + sha = TLV_SHA_TO_SHA_AND_ALG[tlv_type].alg() sha.update(hash_region) return sha.digest() @@ -147,9 +212,16 @@ def get_digest(tlv_type, hash_region): def tlv_matches_key_type(tlv_type, key): """Check if provided key matches to TLV record in the image""" - return (key is None or - type(key) == keys.ECDSA384P1 and tlv_type == TLV_VALUES["SHA384"] or - type(key) != keys.ECDSA384P1 and tlv_type == TLV_VALUES["SHA256"]) + try: + # We do not need the result here, and the key_and_user_sha_to_alg_and_tlv + # will either succeed finding match or rise exception, so on success we + # return True, on exception we return False. + _, _ = key_and_user_sha_to_alg_and_tlv(key, tlv_sha_to_sha(tlv_type)) + return True + except: + pass + + return False class Image: @@ -336,17 +408,13 @@ def ecies_hkdf(self, enckey, plainkey): def create(self, key, public_key_format, enckey, dependencies=None, sw_type=None, custom_tlvs=None, encrypt_keylen=128, clear=False, - fixed_sig=None, pub_key=None, vector_to_sign=None): + fixed_sig=None, pub_key=None, vector_to_sign=None, user_sha='auto'): self.enckey = enckey - # Check what hashing algorithm should be used - if (key and isinstance(key, ecdsa.ECDSA384P1) - or pub_key and isinstance(pub_key, ecdsa.ECDSA384P1Public)): - hash_algorithm = hashlib.sha384 - hash_tlv = "SHA384" - else: - hash_algorithm = hashlib.sha256 - hash_tlv = "SHA256" + # key decides on sha, then pub_key; of both are none default is used + check_key = key if key is not None else pub_key + hash_algorithm, hash_tlv = key_and_user_sha_to_alg_and_tlv(check_key, user_sha) + # Calculate the hash of the public key if key is not None: pub = key.get_public_bytes() @@ -466,11 +534,14 @@ def create(self, key, public_key_format, enckey, dependencies=None, tlv = TLV(self.endian) - # Note that ecdsa wants to do the hashing itself, which means - # we get to hash it twice. + # These signature is done over sha of image. In case of + # EC signatures so called Pure algorithm, designated to be run + # over entire message is used with sha of image as message, + # so, for example, in case of ED25519 we have here SHAxxx-ED25519-SHA512. sha = hash_algorithm() sha.update(self.payload) digest = sha.digest() + message = digest; tlv.add(hash_tlv, digest) if vector_to_sign == 'payload': @@ -499,7 +570,7 @@ def create(self, key, public_key_format, enckey, dependencies=None, sig = key.sign(bytes(self.payload)) else: print(os.path.basename(__file__) + ": sign the digest") - sig = key.sign_digest(digest) + sig = key.sign_digest(message) tlv.add(key.sig_tlv(), sig) self.signature = sig elif fixed_sig is not None and key is None: @@ -678,7 +749,7 @@ def verify(imgfile, key): while tlv_off < tlv_end: tlv = b[tlv_off:tlv_off + TLV_SIZE] tlv_type, _, tlv_len = struct.unpack('BBH', tlv) - if tlv_type == TLV_VALUES["SHA256"] or tlv_type == TLV_VALUES["SHA384"]: + if is_sha_tlv(tlv_type): if not tlv_matches_key_type(tlv_type, key): return VerifyResult.KEY_MISMATCH, None, None off = tlv_off + TLV_SIZE diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index cc2cf9c58..848fd3110 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -72,6 +72,7 @@ def gen_x25519(keyfile, passwd): 'x25519': gen_x25519, } valid_formats = ['openssl', 'pkcs8'] +valid_sha = [ 'auto', '256', '384', '512' ] def load_signature(sigfile): @@ -401,6 +402,9 @@ def convert(self, value, param, ctx): @click.option('--sig-out', metavar='filename', help='Path to the file to which signature will be written. ' 'The image signature will be encoded as base64 formatted string') +@click.option('--sha', 'user_sha', type=click.Choice(valid_sha), default='auto', + help='selected sha algorithm to use; defaults to "auto" which is 256 if ' + 'no cryptographic signature is used, or default for signature type') @click.option('--vector-to-sign', type=click.Choice(['payload', 'digest']), help='send to OUTFILE the payload or payload''s digest instead ' 'of complied image. These data can be used for external image ' @@ -413,7 +417,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, endian, encrypt_keylen, encrypt, infile, outfile, dependencies, load_addr, hex_addr, erased_val, save_enctlv, security_counter, boot_record, custom_tlv, rom_fixed, max_align, clear, fix_sig, - fix_sig_pubkey, sig_out, vector_to_sign, non_bootable): + fix_sig_pubkey, sig_out, user_sha, vector_to_sign, non_bootable): if confirm: # Confirmed but non-padded images don't make much sense, because @@ -481,7 +485,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, img.create(key, public_key_format, enckey, dependencies, boot_record, custom_tlvs, int(encrypt_keylen), clear, baked_signature, - pub_key, vector_to_sign) + pub_key, vector_to_sign, user_sha) img.save(outfile, hex_addr) if sig_out is not None: From 18781c56da59566bcbf658c3dfc80a1365a009de Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 18 Jul 2024 17:47:43 +0000 Subject: [PATCH 215/238] [nrf fromlist] boot: Replace boot_encrypt by boot_enc_encrypt and boot_enc_decrypt To be able to implement encryption with API that requires different calls for encryption and encryption, the boot_encrypt needs to be replaced with encryption/decryption specific functions. Upstream PR: https://github.com/mcu-tools/mcuboot/pull/2017 Signed-off-by: Dominik Ermel --- boot/boot_serial/src/boot_serial_encryption.c | 2 +- boot/bootutil/include/bootutil/enc_key.h | 4 ++- boot/bootutil/src/encrypted.c | 31 ++++++++++++++++--- boot/bootutil/src/image_validate.c | 4 +-- boot/bootutil/src/loader.c | 19 +++++++----- 5 files changed, 44 insertions(+), 16 deletions(-) diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index 7d3b47c72..c4bd7d87b 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -171,7 +171,7 @@ decrypt_region_inplace(struct boot_loader_state *state, blk_sz = tlv_off - (off + bytes_copied); } } - boot_encrypt(BOOT_CURR_ENC(state), slot, + boot_enc_decrypt(BOOT_CURR_ENC(state), slot, (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index 84e05e72f..4ff2432cd 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -70,7 +70,9 @@ int boot_enc_load(struct enc_key_data *enc_state, int slot, const struct image_header *hdr, const struct flash_area *fap, struct boot_status *bs); bool boot_enc_valid(struct enc_key_data *enc_state, int slot); -void boot_encrypt(struct enc_key_data *enc_state, int slot, +void boot_enc_encrypt(struct enc_key_data *enc_state, int slot, + uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); +void boot_enc_decrypt(struct enc_key_data *enc_state, int slot, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); void boot_enc_zeroize(struct enc_key_data *enc_state); diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index d094ea77b..8449a28dd 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -688,14 +688,13 @@ boot_enc_valid(struct enc_key_data *enc_state, int slot) } void -boot_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, +boot_enc_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf) { - struct enc_key_data *enc; + struct enc_key_data *enc = &enc_state[slot]; uint8_t nonce[16]; - /* boot_copy_region will call boot_encrypt with sz = 0 when skipping over - the TLVs. */ + /* Nothing to do with size == 0 */ if (sz == 0) { return; } @@ -707,11 +706,33 @@ boot_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off, nonce[14] = (uint8_t)(off >> 8); nonce[15] = (uint8_t)off; - enc = &enc_state[slot]; assert(enc->valid == 1); bootutil_aes_ctr_encrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf); } +void +boot_enc_decrypt(struct enc_key_data *enc_state, int slot, uint32_t off, + uint32_t sz, uint32_t blk_off, uint8_t *buf) +{ + struct enc_key_data *enc = &enc_state[slot]; + uint8_t nonce[16]; + + /* Nothing to do with size == 0 */ + if (sz == 0) { + return; + } + + memset(nonce, 0, 12); + off >>= 4; + nonce[12] = (uint8_t)(off >> 24); + nonce[13] = (uint8_t)(off >> 16); + nonce[14] = (uint8_t)(off >> 8); + nonce[15] = (uint8_t)off; + + assert(enc->valid == 1); + bootutil_aes_ctr_decrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf); +} + /** * Clears encrypted state after use. */ diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 4db434d6e..a6155f7b0 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -162,8 +162,8 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, if (off >= hdr_size && off < tlv_off) { blk_off = (off - hdr_size) & 0xf; - boot_encrypt(enc_state, slot, off - hdr_size, - blk_sz, blk_off, tmp_buf); + boot_enc_decrypt(enc_state, slot, off - hdr_size, + blk_sz, blk_off, tmp_buf); } } #endif diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 5dfd0419f..7af3e42c0 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1688,9 +1688,15 @@ boot_copy_region(struct boot_loader_state *state, blk_sz = tlv_off - abs_off; } } - boot_encrypt(BOOT_CURR_ENC(state), source_slot, - (abs_off + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, &buf[idx]); + if (source_slot == 0) { + boot_enc_encrypt(BOOT_CURR_ENC(state), source_slot, + (abs_off + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, &buf[idx]); + } else { + boot_enc_decrypt(BOOT_CURR_ENC(state), source_slot, + (abs_off + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, &buf[idx]); + } } } #endif @@ -3253,10 +3259,9 @@ boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state, * Part of the chunk is encrypted payload */ blk_sz = tlv_off - (bytes_copied); } - boot_encrypt(BOOT_CURR_ENC(state), slot, - (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, cur_dst); - + boot_enc_decrypt(BOOT_CURR_ENC(state), slot, + (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, cur_dst); bytes_copied += chunk_sz; } rc = 0; From 6400cc8188d3a4c03d9c4ac120bc4a46b1610d12 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 24 Jul 2024 17:00:04 +0000 Subject: [PATCH 216/238] [nrf noup] PSA configuration required changes Set of changes to Kconfig, CMakeLists.txt and some of headers that are required for the PSA support to compile. Signed-off-by: Dominik Ermel --- boot/bootutil/zephyr/CMakeLists.txt | 14 +++-- boot/zephyr/CMakeLists.txt | 39 ++++++++---- boot/zephyr/Kconfig | 72 ++++++++++++++++++++++- boot/zephyr/include/mcuboot-mbedtls-cfg.h | 2 +- 4 files changed, 111 insertions(+), 16 deletions(-) diff --git a/boot/bootutil/zephyr/CMakeLists.txt b/boot/bootutil/zephyr/CMakeLists.txt index 72a6a8638..d5364d025 100644 --- a/boot/bootutil/zephyr/CMakeLists.txt +++ b/boot/bootutil/zephyr/CMakeLists.txt @@ -29,12 +29,18 @@ zephyr_library_link_libraries(MCUBOOT_BOOTUTIL) target_link_libraries(MCUBOOT_BOOTUTIL INTERFACE zephyr_interface) if(CONFIG_BOOT_USE_TINYCRYPT) -target_include_directories(MCUBOOT_BOOTUTIL INTERFACE - ../../../ext/tinycrypt/lib/include -) + target_include_directories(MCUBOOT_BOOTUTIL INTERFACE + ../../../ext/tinycrypt/lib/include + ) +endif() + +if(CONFIG_BOOT_USE_PSA_CRYPTO) + target_include_directories(MCUBOOT_BOOTUTIL INTERFACE + ${ZEPHYR_MBEDTLS_MODULE_DIR}/include + ) endif() -if(CONFIG_BOOT_USE_MBEDTLS) +if(CONFIG_BOOT_USE_MBEDTLS OR CONFIG_BOOT_USE_PSA_CRYPTO AND NOT CONFIG_PSA_CORE_OBERON) zephyr_link_libraries(mbedTLS) endif() endif() diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index c0a0f0dbe..20831fbe1 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -51,6 +51,12 @@ if(EXISTS targets/${BOARD}.h) zephyr_library_compile_definitions(MCUBOOT_TARGET_CONFIG="${BOARD}.h") endif() +if(DEFINED CONFIG_MBEDTLS) + zephyr_library_include_directories( + ${ZEPHYR_MBEDTLS_MODULE_DIR}/include + ) +endif() + # Zephyr port-specific sources. zephyr_library_sources( main.c @@ -102,6 +108,10 @@ zephyr_library_sources( ${BOOT_DIR}/bootutil/src/fault_injection_hardening.c ) +if(DEFINED CONFIG_BOOT_ENCRYPT_X25519) + zephyr_library_sources(${BOOT_DIR}/bootutil/src/encrypted_psa.c) +endif() + if(DEFINED CONFIG_MEASURED_BOOT OR DEFINED CONFIG_BOOT_SHARE_DATA) zephyr_library_sources( ${BOOT_DIR}/bootutil/src/boot_record.c @@ -230,19 +240,28 @@ elseif(CONFIG_BOOT_SIGNATURE_TYPE_ED25519 OR CONFIG_BOOT_ENCRYPT_X25519) ${FIAT_DIR}/include/ ) - zephyr_library_sources( - ${FIAT_DIR}/src/curve25519.c - ) + if(NOT CONFIG_BOOT_ED25519_PSA) + zephyr_library_sources( + ${FIAT_DIR}/src/curve25519.c + ) + else() + zephyr_library_sources( + ${MBEDTLS_ASN1_DIR}/src/asn1parse.c + ${BOOT_DIR}/bootutil/src/ed25519_psa.c + ) + endif() endif() -if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519) - zephyr_library_sources( - ${TINYCRYPT_DIR}/source/aes_encrypt.c - ${TINYCRYPT_DIR}/source/aes_decrypt.c - ${TINYCRYPT_DIR}/source/ctr_mode.c - ${TINYCRYPT_DIR}/source/hmac.c - ${TINYCRYPT_DIR}/source/ecc_dh.c +if(NOT CONFIG_BOOT_ED25519_PSA) + if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519) + zephyr_library_sources( + ${TINYCRYPT_DIR}/source/aes_encrypt.c + ${TINYCRYPT_DIR}/source/aes_decrypt.c + ${TINYCRYPT_DIR}/source/ctr_mode.c + ${TINYCRYPT_DIR}/source/hmac.c + ${TINYCRYPT_DIR}/source/ecc_dh.c ) + endif() endif() if(CONFIG_BOOT_ENCRYPT_EC256) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index de841ddc1..73f76850e 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -29,7 +29,9 @@ config BOOT_USE_MBEDTLS config BOOT_USE_PSA_CRYPTO bool - # Hidden option + default y if NRF_SECURITY + # This is counter intuitive but that is how PSA heap is enabled. + select MBEDTLS_ENABLE_HEAP help Hidden option set if using PSA crypt for cryptography functionality @@ -66,6 +68,58 @@ config NRF_CC310_BL bool default n +if BOOT_USE_PSA_CRYPTO + +config BOOT_PSA_IMG_HASH_ALG_SHA256_DEPENDENCIES + bool + default y if BOOT_IMG_HASH_ALG_SHA256 + select PSA_WANT_ALG_SHA_256 + help + Dependencies for hashing with SHA256 + +config BOOT_ED25519_PSA_DEPENDENCIES + bool + select PSA_WANT_ALG_SHA_256 + select PSA_WANT_ALG_SHA_512 + select PSA_WANT_ALG_PURE_EDDSA + select PSA_WANT_ECC_TWISTED_EDWARDS_255 + select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT + help + Dependencies for ed25519 signature + +if BOOT_ENCRYPT_IMAGE + +config BOOT_X25519_PSA_DEPENDENCIES + bool + select PSA_WANT_ALG_ECDH + select PSA_WANT_ALG_HMAC + select PSA_WANT_ALG_HKDF + select PSA_WANT_ALG_CTR + select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT + select PSA_WANT_KEY_TYPE_DERIVE + select PSA_WANT_KEY_TYPE_AES + select PSA_WANT_ECC_MONTGOMERY_255 + help + Dependencies for x25519 shared-random key encryption and AES + encryption. The PSA_WANT_ALG_CTR and PSA_WANT_KEY_TYPE_AES + enable Counter based block cipher and AES key, and algorithm support, + to use with it; the others are used for shared key decryption + and derivation. + +endif # BOOT_ENCRYPT_IMAGE + +if MBEDTLS_ENABLE_HEAP + +config MBEDTLS_HEAP_SIZE + default 2048 if BOOT_USE_PSA_CRYPTO + help + The PSA internals need to be able to allocate memory for operation + and it uses mbedTLS heap for that. + +endif # MBEDTLS_ENABLE_HEAP + +endif # BOOT_USE_PSA_CRYPTO + menu "MCUBoot settings" config SINGLE_APPLICATION_SLOT @@ -124,6 +178,7 @@ endchoice # BOOT_IMG_HASH_ALG choice BOOT_SIGNATURE_TYPE prompt "Signature type" + default BOOT_SIGNATURE_TYPE_ED25519 if BOARD_NRF54L15PDK_NRF54L15_CPUAPP default BOOT_SIGNATURE_TYPE_RSA config BOOT_SIGNATURE_TYPE_NONE @@ -178,13 +233,24 @@ if BOOT_SIGNATURE_TYPE_ED25519 choice BOOT_ED25519_IMPLEMENTATION prompt "Ecdsa implementation" default BOOT_ED25519_TINYCRYPT + config BOOT_ED25519_TINYCRYPT bool "Use tinycrypt" select BOOT_USE_TINYCRYPT + depends on !NRF_SECURITY + config BOOT_ED25519_MBEDTLS bool "Use mbedTLS" select BOOT_USE_MBEDTLS select MBEDTLS + depends on !NRF_SECURITY + +config BOOT_ED25519_PSA + bool "Use PSA crypto" + select BOOT_USE_PSA_CRYPTO + select BOOT_ED25519_PSA_DEPENDENCIES + select BOOT_X25519_PSA_DEPENDENCIES if BOOT_ENCRYPT_IMAGE + endchoice endif @@ -223,9 +289,13 @@ config MCUBOOT_CLEANUP_ARM_CORE start-up code which can cause a module fault and potentially make the module irrecoverable. +if MBEDTLS + config MBEDTLS_CFG_FILE default "mcuboot-mbedtls-cfg.h" +endif + config BOOT_HW_KEY bool "Use HW key for image verification" default n diff --git a/boot/zephyr/include/mcuboot-mbedtls-cfg.h b/boot/zephyr/include/mcuboot-mbedtls-cfg.h index 2bab537d7..a46fbb09f 100644 --- a/boot/zephyr/include/mcuboot-mbedtls-cfg.h +++ b/boot/zephyr/include/mcuboot-mbedtls-cfg.h @@ -23,7 +23,7 @@ #if defined(CONFIG_BOOT_SIGNATURE_TYPE_RSA) || defined(CONFIG_BOOT_ENCRYPT_RSA) #include "config-rsa.h" -#elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) || \ +#elif defined(CONFIG_BOOT_USE_PSA_CRYPTO) || defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) || \ defined(CONFIG_BOOT_ENCRYPT_EC256) || \ (defined(CONFIG_BOOT_ENCRYPT_X25519) && !defined(CONFIG_BOOT_SIGNATURE_TYPE_ED25519)) #include "config-asn1.h" From e874cf8e2fc6d2f86ddfeeb09801d418b16957f1 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 29 May 2024 17:46:17 +0000 Subject: [PATCH 217/238] [nrf noup] PSA implementation of x25519 and ed25519 verification The commit provides implementation of image verification with ed25519 and encryption/decryption support where random key is encrypted using x25519. Signed-off-by: Dominik Ermel --- .../include/bootutil/crypto/aes_ctr.h | 38 +- boot/bootutil/src/ed25519_psa.c | 71 +++ boot/bootutil/src/encrypted.c | 114 ++--- boot/bootutil/src/encrypted_psa.c | 453 ++++++++++++++++++ boot/bootutil/src/image_ed25519.c | 18 +- 5 files changed, 634 insertions(+), 60 deletions(-) create mode 100644 boot/bootutil/src/ed25519_psa.c create mode 100644 boot/bootutil/src/encrypted_psa.c diff --git a/boot/bootutil/include/bootutil/crypto/aes_ctr.h b/boot/bootutil/include/bootutil/crypto/aes_ctr.h index e69b0372f..fd2416176 100644 --- a/boot/bootutil/include/bootutil/crypto/aes_ctr.h +++ b/boot/bootutil/include/bootutil/crypto/aes_ctr.h @@ -15,8 +15,8 @@ #include "mcuboot_config/mcuboot_config.h" #if (defined(MCUBOOT_USE_MBED_TLS) + \ - defined(MCUBOOT_USE_TINYCRYPT)) != 1 - #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT" + defined(MCUBOOT_USE_TINYCRYPT) + defined(MCUBOOT_USE_PSA_CRYPTO)) != 1 + #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT or PSA" #endif #if defined(MCUBOOT_USE_MBED_TLS) @@ -38,12 +38,46 @@ #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE TC_AES_BLOCK_SIZE #endif /* MCUBOOT_USE_TINYCRYPT */ + +#if defined(MCUBOOT_USE_PSA_CRYPTO) + #include + #include "bootutil/enc_key_public.h" + #define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE BOOT_ENC_KEY_SIZE + #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16) +#endif + #include #ifdef __cplusplus extern "C" { #endif +#if defined(MCUBOOT_USE_PSA_CRYPTO) +typedef struct { + /* Fixme: This should not be, here, psa_key_id should be passed */ + uint8_t key[BOOT_ENC_KEY_SIZE]; +} bootutil_aes_ctr_context; + +void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx); + +static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx) +{ + memset(ctx, 0, sizeof(ctx)); +} + +static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k) +{ + memcpy(ctx->key, k, sizeof(ctx->key)); + + return 0; +} + +int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, + const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c); +int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, + const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m); +#endif + #if defined(MCUBOOT_USE_MBED_TLS) typedef mbedtls_aes_context bootutil_aes_ctr_context; static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx) diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c new file mode 100644 index 000000000..3d7274307 --- /dev/null +++ b/boot/bootutil/src/ed25519_psa.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include +#include + +#include +#include "bootutil/bootutil_log.h" + +#include +#include + +BOOT_LOG_MODULE_DECLARE(ed25519_psa); + +#define SHA512_DIGEST_LENGTH 64 +#define EDDSA_KEY_LENGTH 32 +#define EDDSA_SIGNAGURE_LENGTH 64 + +int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], + const uint8_t public_key[EDDSA_KEY_LENGTH]) +{ + /* Set to any error */ + psa_status_t status = PSA_ERROR_BAD_STATE; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t kid; + int ret = 0; /* Fail by default */ + + /* Initialize PSA Crypto */ + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + BOOT_LOG_ERR("PSA crypto init failed %d\n", status); + return 0; + } + + status = PSA_ERROR_BAD_STATE; + + psa_set_key_type(&key_attr, + PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS)); + psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&key_attr, PSA_ALG_PURE_EDDSA); + + status = psa_import_key(&key_attr, public_key, EDDSA_KEY_LENGTH, &kid); + if (status != PSA_SUCCESS) { + BOOT_LOG_ERR("ED25519 key import failed %d", status); + return 0; + } + + status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, message_len, + signature, EDDSA_SIGNAGURE_LENGTH); + if (status != PSA_SUCCESS) { + BOOT_LOG_ERR("ED25519 signature verification failed %d", status); + ret = 0; + /* Pass through to destroy key */ + } else { + ret = 1; + /* Pass through to destroy key */ + } + + status = psa_destroy_key(kid); + + if (status != PSA_SUCCESS) { + /* Just for logging */ + BOOT_LOG_WRN("Failed to destroy key %d", status); + } + + return ret; +} diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index 8449a28dd..67fa819bb 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -25,6 +25,7 @@ #include "bootutil/crypto/ecdh_p256.h" #endif +#if !defined(MCUBOOT_USE_PSA_CRYPTO) #if defined(MCUBOOT_ENCRYPT_X25519) #include "bootutil/crypto/ecdh_x25519.h" #endif @@ -35,6 +36,7 @@ #include "mbedtls/oid.h" #include "mbedtls/asn1.h" #endif +#endif #include "bootutil/image.h" #include "bootutil/enc_key.h" @@ -43,6 +45,30 @@ #include "bootutil_priv.h" +#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE + +#if defined(MCUBOOT_ENCRYPT_RSA) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048 +#elif defined(MCUBOOT_ENCRYPT_KW) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW +#elif defined(MCUBOOT_ENCRYPT_EC256) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256 +# define EC_PUBK_INDEX (0) +# define EC_TAG_INDEX (65) +# define EC_CIPHERKEY_INDEX (65 + 32) +_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, + "Please fix ECIES-P256 component indexes"); +#elif defined(MCUBOOT_ENCRYPT_X25519) +# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519 +# define EC_PUBK_INDEX (0) +# define EC_TAG_INDEX (32) +# define EC_CIPHERKEY_INDEX (32 + 32) +_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, + "Please fix ECIES-X25519 component indexes"); +#endif + +/* NOUP Fixme: */ +#if !defined(CONFIG_BOOT_ED25519_PSA) #if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519) #if defined(_compare) static inline int bootutil_constant_time_compare(const uint8_t *a, const uint8_t *b, size_t size) @@ -351,60 +377,6 @@ int boot_enc_retrieve_private_key(struct bootutil_key **private_key) } #endif /* !MCUBOOT_ENC_BUILTIN_KEY */ -int -boot_enc_init(struct enc_key_data *enc_state, uint8_t slot) -{ - bootutil_aes_ctr_init(&enc_state[slot].aes_ctr); - return 0; -} - -int -boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot) -{ - bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr); - enc_state[slot].valid = 0; - return 0; -} - -int -boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, - const struct boot_status *bs) -{ - int rc; - - rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]); - if (rc != 0) { - boot_enc_drop(enc_state, slot); - return -1; - } - - enc_state[slot].valid = 1; - - return 0; -} - -#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE - -#if defined(MCUBOOT_ENCRYPT_RSA) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048 -#elif defined(MCUBOOT_ENCRYPT_KW) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW -#elif defined(MCUBOOT_ENCRYPT_EC256) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256 -# define EC_PUBK_INDEX (0) -# define EC_TAG_INDEX (65) -# define EC_CIPHERKEY_INDEX (65 + 32) -_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, - "Please fix ECIES-P256 component indexes"); -#elif defined(MCUBOOT_ENCRYPT_X25519) -# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519 -# define EC_PUBK_INDEX (0) -# define EC_TAG_INDEX (32) -# define EC_CIPHERKEY_INDEX (32 + 32) -_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, - "Please fix ECIES-X25519 component indexes"); -#endif - #if ( (defined(MCUBOOT_ENCRYPT_RSA) && defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_PSA_CRYPTO)) || \ (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS)) ) #if MBEDTLS_VERSION_NUMBER >= 0x03000000 @@ -627,6 +599,7 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey) return rc; } +#endif /* CONFIG_BOOT_ED25519_PSA */ /* * Load encryption key. @@ -681,6 +654,39 @@ boot_enc_load(struct enc_key_data *enc_state, int slot, return boot_decrypt_key(buf, bs->enckey[slot]); } +int +boot_enc_init(struct enc_key_data *enc_state, uint8_t slot) +{ + bootutil_aes_ctr_init(&enc_state[slot].aes_ctr); + return 0; +} + +int +boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot) +{ + bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr); + enc_state[slot].valid = 0; + return 0; +} + +int +boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, + const struct boot_status *bs) +{ + int rc; + + rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]); + if (rc != 0) { + boot_enc_drop(enc_state, slot); + return -1; + } + + enc_state[slot].valid = 1; + + return 0; +} + + bool boot_enc_valid(struct enc_key_data *enc_state, int slot) { diff --git a/boot/bootutil/src/encrypted_psa.c b/boot/bootutil/src/encrypted_psa.c new file mode 100644 index 000000000..927ce2d6b --- /dev/null +++ b/boot/bootutil/src/encrypted_psa.c @@ -0,0 +1,453 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "mcuboot_config/mcuboot_config.h" + +#include +#include +#include + +/* We are not really using the MBEDTLS but need the ASN.1 parsing functions */ +#define MBEDTLS_ASN1_PARSE_C + +#include "bootutil/crypto/sha.h" +#include "mbedtls/oid.h" +#include "mbedtls/asn1.h" + +#include "bootutil/image.h" +#include "bootutil/enc_key.h" +#include "bootutil/sign_key.h" +#include "bootutil/crypto/common.h" + +#include "bootutil_priv.h" +#include "bootutil/bootutil_log.h" + +BOOT_LOG_MODULE_DECLARE(mcuboot_psa_enc); + +#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE +#define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519 +#define EC_PUBK_INDEX (0) +#define EC_TAG_INDEX (32) +#define EC_CIPHERKEY_INDEX (32 + 32) +_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN, + "Please fix ECIES-X25519 component indexes"); + +#define X25519_OID "\x6e" +static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG \ + MBEDTLS_OID_ORG_GOV X25519_OID; + +#define SHARED_KEY_LEN 32 +#define PRIV_KEY_LEN 32 + +/* Fixme: This duplicates code from encrypted.c and depends on mbedtls */ +static int +parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key) +{ + size_t len; + int version; + mbedtls_asn1_buf alg; + mbedtls_asn1_buf param; + + if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE) != 0) { + return -1; + } + + if (*p + len != end) { + return -2; + } + + version = 0; + if (mbedtls_asn1_get_int(p, end, &version) || version != 0) { + return -3; + } + + if (mbedtls_asn1_get_alg(p, end, &alg, ¶m) != 0) { + return -4; + } + + if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 || + memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) { + return -5; + } + + if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) { + return -6; + } + + if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) { + return -7; + } + + if (len != PRIV_KEY_LEN) { + return -8; + } + + memcpy(private_key, *p, PRIV_KEY_LEN); + return 0; +} + +void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx) +{ + psa_status_t psa_ret = psa_crypto_init(); + + (void)ctx; + + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES init PSA crypto init failed %d", psa_ret); + assert(0); + } +} + +#if defined(MCUBOOT_ENC_IMAGES) +/* + * Decrypt an encryption key TLV. + * + * @param buf An encryption TLV read from flash (build time fixed length) + * @param enckey An AES-128 or AES-256 key sized buffer to store to plain key. + */ +int +boot_decrypt_key(const uint8_t *buf, uint8_t *enckey) +{ + uint8_t derived_key[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE]; + uint8_t *cp; + uint8_t *cpend; + uint8_t private_key[PRIV_KEY_LEN]; + size_t len; + psa_status_t psa_ret = PSA_ERROR_BAD_STATE; + psa_status_t psa_cleanup_ret = PSA_ERROR_BAD_STATE; + psa_key_id_t kid; + psa_key_attributes_t kattr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_derivation_operation_t key_do = PSA_KEY_DERIVATION_OPERATION_INIT; + psa_algorithm_t key_do_alg; + int rc = -1; + + cp = (uint8_t *)bootutil_enc_key.key; + cpend = cp + *bootutil_enc_key.len; + + /* The psa_cipher_decrypt needs initialization vector of proper length at + * the beginning of the input buffer. + */ + uint8_t iv_and_key[PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR) + + BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE]; + + psa_ret = psa_crypto_init(); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES crypto init failed %d", psa_ret); + return -1; + } + + /* + * Load the stored X25519 decryption private key + */ + rc = parse_x25519_enckey(&cp, cpend, private_key); + if (rc) { + return rc; + } + + psa_set_key_type(&kattr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY)); + psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&kattr, PSA_ALG_ECDH); + + psa_ret = psa_import_key(&kattr, private_key, sizeof(private_key), &kid); + memset(private_key, 0, sizeof(private_key)); + psa_reset_key_attributes(&kattr); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("Built-in key import failed %d", psa_ret); + return -1; + } + + key_do_alg = PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)); + + psa_ret = psa_key_derivation_setup(&key_do, key_do_alg); + if (psa_ret != PSA_SUCCESS) { + psa_cleanup_ret = psa_destroy_key(kid); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("Built-in key destruction failed %d", psa_cleanup_ret); + } + BOOT_LOG_ERR("Key derivation setup failed %d", psa_ret); + return -1; + } + + /* Note: PSA 1.1.2 does not have psa_key_agreement that would be useful here + * as it could just add the derived key to the storage and return key id. + * Instead, we have to use the code below to generate derived key and put it + * into storage, to obtain the key id we can then use with psa_mac_* functions. + */ + psa_ret = psa_key_derivation_key_agreement(&key_do, PSA_KEY_DERIVATION_INPUT_SECRET, + kid, &buf[EC_PUBK_INDEX], + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE); + psa_cleanup_ret = psa_destroy_key(kid); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("Built-in key destruction failed %d", psa_cleanup_ret); + } + if (psa_ret != PSA_SUCCESS) { + psa_cleanup_ret = psa_key_derivation_abort(&key_do); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("Key derivation abort failed %d", psa_ret); + } + + BOOT_LOG_ERR("Key derivation failed %d", psa_ret); + return -1; + } + + /* Only info, no salt */ + psa_ret = psa_key_derivation_input_bytes(&key_do, PSA_KEY_DERIVATION_INPUT_INFO, + "MCUBoot_ECIES_v1", 16); + if (psa_ret != PSA_SUCCESS) { + psa_cleanup_ret = psa_key_derivation_abort(&key_do); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("Key derivation abort failed %d", psa_ret); + } + BOOT_LOG_ERR("Key derivation failed %d", psa_ret); + return -1; + } + + len = BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE; + psa_ret = psa_key_derivation_output_bytes(&key_do, derived_key, len); + psa_cleanup_ret = psa_key_derivation_abort(&key_do); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("Key derivation cleanup failed %d", psa_ret); + } + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("Key derivation failed %d", psa_ret); + return -1; + } + + /* The derived key consists of BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE bytes + * followed by BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE bytes. Both parts will + * be imported at the point where needed and discarded immediately after. + */ + psa_set_key_type(&kattr, PSA_KEY_TYPE_HMAC); + psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&kattr, PSA_ALG_HMAC(PSA_ALG_SHA_256)); + + /* Import the MAC tag key part of derived key, that is the part that starts + * after BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE and has length of + * BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE bytes. + */ + psa_ret = psa_import_key(&kattr, + &derived_key[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE], + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE, &kid); + psa_reset_key_attributes(&kattr); + if (psa_ret != PSA_SUCCESS) { + memset(derived_key, 0, sizeof(derived_key)); + BOOT_LOG_ERR("MAC key import failed %d", psa_ret); + return -1; + } + + /* Verify the MAC tag of the random encryption key */ + psa_ret = psa_mac_verify(kid, PSA_ALG_HMAC(PSA_ALG_SHA_256), + &buf[EC_CIPHERKEY_INDEX], BOOT_ENC_KEY_SIZE, + &buf[EC_TAG_INDEX], + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE); + psa_cleanup_ret = psa_destroy_key(kid); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("MAC key destruction failed %d", psa_cleanup_ret); + } + if (psa_ret != PSA_SUCCESS) { + memset(derived_key, 0, sizeof(derived_key)); + BOOT_LOG_ERR("MAC verification failed %d", psa_ret); + return -1; + } + + /* The derived key is used in AES decryption of random key */ + psa_set_key_type(&kattr, PSA_KEY_TYPE_AES); + psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&kattr, PSA_ALG_CTR); + + /* Import the AES partition of derived key, the first 16 bytes */ + psa_ret = psa_import_key(&kattr, &derived_key[0], + BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE, &kid); + memset(derived_key, 0, sizeof(derived_key)); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES key import failed %d", psa_ret); + return -1; + } + + /* Decrypt the random AES encryption key with AES and the key obtained + * at derivation. */ + memset(&iv_and_key[0], 0, PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR)); + memcpy(&iv_and_key[PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR)], + &buf[EC_CIPHERKEY_INDEX], + sizeof(iv_and_key) - PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CTR)); + + len = 0; + psa_ret = psa_cipher_decrypt(kid, PSA_ALG_CTR, iv_and_key, sizeof(iv_and_key), + enckey, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE, &len); + memset(iv_and_key, 0, sizeof(iv_and_key)); + psa_cleanup_ret = psa_destroy_key(kid); + if (psa_cleanup_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("AES key destruction failed %d", psa_cleanup_ret); + } + if (psa_ret != PSA_SUCCESS || len != BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE) { + memset(enckey, 0, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE); + BOOT_LOG_ERR("Random key decryption failed %d", psa_ret); + return -1; + } + + return 0; +} + +int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, + const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c) +{ + int ret = 0; + psa_status_t psa_ret = PSA_ERROR_BAD_STATE; + psa_key_attributes_t kattr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t kid; + psa_cipher_operation_t psa_op; + size_t elen = 0; /* Decrypted length */ + + /* Fixme: calling psa_crypto_init multiple times is not a problem, + * yet the code here is only present because there is not general + * crypto init. */ + psa_ret = psa_crypto_init(); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("PSA crypto init failed %d", psa_ret); + ret = -1; + goto gone; + } + + psa_op = psa_cipher_operation_init(); + + /* Fixme: Import should happen when key is decrypted, but due to lack + * of key destruction there is no way to destroy key stored by + * psa other way than here. */ + psa_set_key_type(&kattr, PSA_KEY_TYPE_AES); + psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&kattr, PSA_ALG_CTR); + + psa_ret = psa_import_key(&kattr, ctx->key, BOOT_ENC_KEY_SIZE, &kid); + psa_reset_key_attributes(&kattr); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES enc import key failed %d", psa_ret); + ret = -1; + goto gone; + } + + /* This could be done with psa_cipher_decrypt one-shot operation, but + * multi-part operation is used to avoid re-allocating input buffer + * to account for IV in front of data. + */ + psa_ret = psa_cipher_encrypt_setup(&psa_op, kid, PSA_ALG_CTR); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES enc setup failed %d", psa_ret); + ret = -1; + goto gone_with_key; + } + + /* Fixme: hardcoded counter size, but it is hardcoded everywhere */ + psa_ret = psa_cipher_set_iv(&psa_op, counter, 16); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES enc IV set failed %d", psa_ret); + ret = -1; + goto gone_after_setup; + } + + psa_ret = psa_cipher_update(&psa_op, m, mlen, c, mlen, &elen); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES enc encryption failed %d", psa_ret); + ret = -1; + goto gone_after_setup; + } + +gone_after_setup: + psa_ret = psa_cipher_abort(&psa_op); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("AES enc cipher abort failed %d", psa_ret); + /* Intentionally not changing the ret */ + } +gone_with_key: + /* Fixme: Should be removed once key is shared by id */ + psa_ret = psa_destroy_key(kid); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("AES enc destroy key failed %d", psa_ret); + /* Intentionally not changing the ret */ + } +gone: + return ret; +} + +int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, + const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m) +{ + int ret = 0; + psa_status_t psa_ret = PSA_ERROR_BAD_STATE; + psa_key_attributes_t kattr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t kid; + psa_cipher_operation_t psa_op; + size_t dlen = 0; /* Decrypted length */ + + /* Fixme: the init should already happen before calling the function, but + * somehow it does not, for example when recovering in swap. + */ + psa_ret = psa_crypto_init(); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("PSA crypto init failed %d", psa_ret); + ret = -1; + goto gone; + } + + psa_op = psa_cipher_operation_init(); + + /* Fixme: Import should happen when key is decrypted, but due to lack + * of key destruction there is no way to destroy key stored by + * psa other way than here. */ + psa_set_key_type(&kattr, PSA_KEY_TYPE_AES); + psa_set_key_usage_flags(&kattr, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&kattr, PSA_ALG_CTR); + + psa_ret = psa_import_key(&kattr, ctx->key, BOOT_ENC_KEY_SIZE, &kid); + psa_reset_key_attributes(&kattr); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES dec import key failed %d", psa_ret); + ret = -1; + goto gone; + } + + /* This could be done with psa_cipher_decrypt one-shot operation, but + * multi-part operation is used to avoid re-allocating input buffer + * to account for IV in front of data. + */ + psa_ret = psa_cipher_decrypt_setup(&psa_op, kid, PSA_ALG_CTR); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES dec setup failed %d", psa_ret); + ret = -1; + goto gone_with_key; + } + + /* Fixme: hardcoded counter size, but it is hardcoded everywhere */ + psa_ret = psa_cipher_set_iv(&psa_op, counter, 16); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES dec IV set failed %d", psa_ret); + ret = -1; + goto gone_after_setup; + } + + psa_ret = psa_cipher_update(&psa_op, c, clen, m, clen, &dlen); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_ERR("AES dec decryption failed %d", psa_ret); + ret = -1; + goto gone_after_setup; + } + +gone_after_setup: + psa_ret = psa_cipher_abort(&psa_op); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("PSA dec abort failed %d", psa_ret); + /* Intentionally not changing the ret */ + } +gone_with_key: + psa_ret = psa_destroy_key(kid); + if (psa_ret != PSA_SUCCESS) { + BOOT_LOG_WRN("PSA dec key failed %d", psa_ret); + /* Intentionally not changing the ret */ + } +gone: + return ret; +} +#endif /* defined(MCUBOOT_ENC_IMAGES) */ diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 7a597d4c0..c3e8410f1 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -9,6 +9,11 @@ #include "mcuboot_config/mcuboot_config.h" +#if defined(CONFIG_NRF_SECURITY) +/* We are not really using the MBEDTLS but need the ASN.1 parsing funcitons */ +#define MBEDTLS_ASN1_PARSE_C +#endif + #ifdef MCUBOOT_SIGN_ED25519 #include "bootutil/sign_key.h" @@ -18,12 +23,16 @@ #include "bootutil_priv.h" #include "bootutil/crypto/common.h" +#define SHA512_LEN 64 +#define SHA256_LEN 32 +#define EDDSA_SIGNAGURE_LENGTH 64 + static const uint8_t ed25519_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x65\x70"; #define NUM_ED25519_BYTES 32 extern int ED25519_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[64], - const uint8_t public_key[32]); + const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], + const uint8_t public_key[NUM_ED25519_BYTES]); /* * Parse the public key used for signing. @@ -73,7 +82,8 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, uint8_t *pubkey; uint8_t *end; - if (hlen != 32 || slen != 64) { + if (!(hlen == SHA512_LEN || hlen == SHA256_LEN) || + slen != EDDSA_SIGNAGURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } @@ -87,7 +97,7 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, goto out; } - rc = ED25519_verify(hash, 32, sig, pubkey); + rc = ED25519_verify(hash, hlen, sig, pubkey); if (rc == 0) { /* if verify returns 0, there was an error. */ From 2d7b4a6242fb639817b5482dc862eccc52e0fd88 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 1 Oct 2024 10:35:26 +0000 Subject: [PATCH 218/238] [nrf noup] Exclude PSA source on non-PSA crypto configuration fixup! [nrf noup] PSA configuration required changes Signed-off-by: Dominik Ermel --- boot/zephyr/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 20831fbe1..20d38b49b 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -108,7 +108,7 @@ zephyr_library_sources( ${BOOT_DIR}/bootutil/src/fault_injection_hardening.c ) -if(DEFINED CONFIG_BOOT_ENCRYPT_X25519) +if(DEFINED CONFIG_BOOT_ENCRYPT_X25519 AND DEFINED CONFIG_BOOT_ED25519_PSA) zephyr_library_sources(${BOOT_DIR}/bootutil/src/encrypted_psa.c) endif() From ccb95529b3b4fa2ba3c6a0f8d4ffe9b685cc0673 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 2 Aug 2024 15:55:13 +0000 Subject: [PATCH 219/238] [nrf noup] bootutil: Provide support for SHA512 with ED25519 Use SHA512 directly calculated over image with the ED25519 signature. Signed-off-by: Dominik Ermel --- boot/zephyr/Kconfig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 73f76850e..204aad4d8 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -79,7 +79,7 @@ config BOOT_PSA_IMG_HASH_ALG_SHA256_DEPENDENCIES config BOOT_ED25519_PSA_DEPENDENCIES bool - select PSA_WANT_ALG_SHA_256 + select PSA_WANT_ALG_SHA_256 if BOOT_IMG_HASH_ALG_SHA256 select PSA_WANT_ALG_SHA_512 select PSA_WANT_ALG_PURE_EDDSA select PSA_WANT_ECC_TWISTED_EDWARDS_255 @@ -228,6 +228,11 @@ config BOOT_SIGNATURE_TYPE_ED25519 bool "Edwards curve digital signatures using ed25519" select BOOT_ENCRYPTION_SUPPORT select BOOT_IMG_HASH_ALG_SHA256_ALLOW + select BOOT_IMG_HASH_ALG_SHA512_ALLOW + help + This is ed25519 signature calculated over SHA512 of SHA256 of application + image; that is not completely correct approach as the SHA512 should be + rather directly calculated over an image. if BOOT_SIGNATURE_TYPE_ED25519 choice BOOT_ED25519_IMPLEMENTATION From 258b36998f7a400ae3b38d6d1b01f57722e2004b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 5 Sep 2024 10:53:17 +0000 Subject: [PATCH 220/238] [nrf noup] bootutil: Enable hash calculation directly on storage The commit add support for passing storage device address space to hash calculation functions, which allows to use hardware accelerated hash calculation on storage. This feature only works when image encryption is not enabled and all slots are defined within internal storage of device. The feature is enabled using Kconfig option CONFIG_BOOT_IMG_HASH_DIRECTLY_ON_STORAGE Signed-off-by: Dominik Ermel --- boot/bootutil/src/image_validate.c | 15 ++++++++++++--- boot/zephyr/Kconfig | 16 ++++++++++++++++ .../include/mcuboot_config/mcuboot_config.h | 7 +++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index a6155f7b0..12a9a7188 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -77,13 +77,15 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, uint8_t *seed, int seed_len) { bootutil_sha_context sha_ctx; - uint32_t blk_sz; uint32_t size; uint16_t hdr_size; - uint32_t off; - int rc; uint32_t blk_off; uint32_t tlv_off; +#if !defined(MCUBOOT_HASH_STORAGE_DIRECTLY) + int rc; + uint32_t off; + uint32_t blk_sz; +#endif #if (BOOT_IMAGE_NUMBER == 1) || !defined(MCUBOOT_ENC_IMAGES) || \ defined(MCUBOOT_RAM_LOAD) @@ -126,6 +128,12 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, /* If protected TLVs are present they are also hashed. */ size += hdr->ih_protect_tlv_size; +#ifdef MCUBOOT_HASH_STORAGE_DIRECTLY + /* No chunk loading, storage is mapped to address space and can + * be directly given to hashing function. + */ + bootutil_sha_update(&sha_ctx, (void *)flash_area_get_off(fap), size); +#else /* MCUBOOT_HASH_STORAGE_DIRECTLY */ #ifdef MCUBOOT_RAM_LOAD bootutil_sha_update(&sha_ctx, (void*)(IMAGE_RAM_BASE + hdr->ih_load_addr), @@ -170,6 +178,7 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, bootutil_sha_update(&sha_ctx, tmp_buf, blk_sz); } #endif /* MCUBOOT_RAM_LOAD */ +#endif /* MCUBOOT_HASH_STORAGE_DIRECTLY */ bootutil_sha_finish(&sha_ctx, hash_result); bootutil_sha_drop(&sha_ctx); diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 204aad4d8..d3676e107 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -146,6 +146,22 @@ config BOOT_IMG_HASH_ALG_SHA512_ALLOW help Hidden option set by configurations that allow SHA512 +config BOOT_IMG_HASH_DIRECTLY_ON_STORAGE + bool "Hash calculation functions access storage through address space" + depends on !BOOT_ENCRYPT_IMAGE + help + When possible to map storage device, at least for read operations, + to address space or RAM area, enabling this option allows hash + calculation functions to directly access the storage through that address + space or using its own DMA. This reduces flash read overhead done + by the MCUboot. + Notes: + - not supported when encrypted images are in use, because calculating + SHA requires image to be decrypted first, which is done to RAM. + - currently only supported on internal storage of devices; this + option will not work with devices that use external storage for + either of image slots. + choice BOOT_IMG_HASH_ALG prompt "Selected image hash algorithm" default BOOT_IMG_HASH_ALG_SHA256 if BOOT_IMG_HASH_ALG_SHA256_ALLOW diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index f628f99c4..fbd64b5e7 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -140,6 +140,13 @@ #define MCUBOOT_DECOMPRESS_IMAGES #endif +/* Invoke hashing functions directly on storage. This requires for device + * to be able to map storage to address space or RAM. + */ +#ifdef CONFIG_BOOT_IMG_HASH_DIRECTLY_ON_STORAGE +#define MCUBOOT_HASH_STORAGE_DIRECTLY +#endif + #ifdef CONFIG_BOOT_BOOTSTRAP #define MCUBOOT_BOOTSTRAP 1 #endif From d1b85af4e5a65a0e98b637c20f230d4bedda8808 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 6 Sep 2024 16:16:28 +0000 Subject: [PATCH 221/238] [nrf noup] bootutil: PureEdDSA using ED25519 The commit adds support for PureEdDSA, which validates signature of image rather than hash. This is most secure, available, ED25519 usage in MCUboot, but due to requirement of PureEdDSA to be able to calculate signature at whole message at once, here image, it only works on setups where entire image can be mapped to device address space, so that PSA functions calculating the signature can see the whole image at once. This option is enabled with Kconfig option: CONFIG_BOOT_SIGNATURE_TYPE_PURE when the ED25519 signature type is already selected. Note that the option will enable SHA512 for calculating public key hash. Signed-off-by: Dominik Ermel --- boot/bootutil/include/bootutil/image.h | 3 + boot/bootutil/src/bootutil_priv.h | 3 + boot/bootutil/src/image_ed25519.c | 37 ++++++++ boot/bootutil/src/image_validate.c | 87 +++++++++++++++++-- boot/zephyr/Kconfig | 29 ++++++- .../include/mcuboot_config/mcuboot_config.h | 4 + 6 files changed, 155 insertions(+), 8 deletions(-) diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 9ede800a2..836712458 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -102,6 +102,9 @@ struct flash_area; #define IMAGE_TLV_ECDSA_SIG 0x22 /* ECDSA of hash output */ #define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */ #define IMAGE_TLV_ED25519 0x24 /* ed25519 of hash output */ +#define IMAGE_TLV_SIG_PURE 0x25 /* Whatever signature has been selected, it will be used + * as "pure" where signature is verified over entire + * image rather than hash of an image */ #define IMAGE_TLV_ENC_RSA2048 0x30 /* Key encrypted with RSA-OAEP-2048 */ #define IMAGE_TLV_ENC_KW 0x31 /* Key encrypted with AES-KW 128 or 256*/ #define IMAGE_TLV_ENC_EC256 0x32 /* Key encrypted with ECIES-EC256 */ diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h index 208d189b9..c23f61689 100644 --- a/boot/bootutil/src/bootutil_priv.h +++ b/boot/bootutil/src/bootutil_priv.h @@ -268,6 +268,9 @@ struct boot_loader_state { fih_ret bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, uint8_t key_id); +fih_ret bootutil_verify_img(const uint8_t *img, uint32_t size, + uint8_t *sig, size_t slen, uint8_t key_id); + fih_ret boot_fih_memequal(const void *s1, const void *s2, size_t n); int boot_find_status(int image_index, const struct flash_area **fap); diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index c3e8410f1..984a58302 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -111,4 +111,41 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, FIH_RET(fih_rc); } +fih_ret +bootutil_verify_img(const uint8_t *img, uint32_t size, + uint8_t *sig, size_t slen, uint8_t key_id) +{ + int rc; + FIH_DECLARE(fih_rc, FIH_FAILURE); + uint8_t *pubkey; + uint8_t *end; + + if (slen != EDDSA_SIGNAGURE_LENGTH) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + + pubkey = (uint8_t *)bootutil_keys[key_id].key; + end = pubkey + *bootutil_keys[key_id].len; + + rc = bootutil_import_key(&pubkey, end); + if (rc) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + + rc = ED25519_verify(img, size, sig, pubkey); + + if (rc == 0) { + /* if verify returns 0, there was an error. */ + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + + FIH_SET(fih_rc, FIH_SUCCESS); +out: + + FIH_RET(fih_rc); +} + #endif /* MCUBOOT_SIGN_ED25519 */ diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 12a9a7188..1ba0f7b23 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -65,6 +65,7 @@ BOOT_LOG_MODULE_DECLARE(mcuboot); #include "bootutil_priv.h" +#ifndef MCUBOOT_SIGN_PURE /* * Compute SHA hash over the image. * (SHA384 if ECDSA-P384 is being used, @@ -184,6 +185,7 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index, return 0; } +#endif /* * Currently, we only support being able to verify one type of @@ -370,6 +372,35 @@ bootutil_get_img_security_cnt(struct image_header *hdr, return 0; } +#if defined(MCUBOOT_SIGN_PURE) +/* Returns: + * 0 -- found + * 1 -- not found + * -1 -- failed for some reason + * + * Value of TLV does not matter, presence decides. + */ +static int bootutil_check_for_pure(const struct image_header *hdr, + const struct flash_area *fap) +{ + struct image_tlv_iter it; + uint32_t off; + uint16_t len; + int32_t rc; + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_SIG_PURE, false); + if (rc) { + return rc; + } + + /* Search for the TLV */ + rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); + + return rc; +} +#endif + + #ifndef ALLOW_ROGUE_TLVS /* * The following list of TLVs are the only entries allowed in the unprotected @@ -386,6 +417,9 @@ static const uint16_t allowed_unprot_tlvs[] = { IMAGE_TLV_ECDSA_SIG, IMAGE_TLV_RSA3072_PSS, IMAGE_TLV_ED25519, +#if defined(MCUBOOT_SIGN_PURE) + IMAGE_TLV_SIG_PURE, +#endif IMAGE_TLV_ENC_RSA2048, IMAGE_TLV_ENC_KW, IMAGE_TLV_ENC_EC256, @@ -408,7 +442,6 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, uint32_t off; uint16_t len; uint16_t type; - int image_hash_valid = 0; #ifdef EXPECTED_SIG_TLV FIH_DECLARE(valid_signature, FIH_FAILURE); #ifndef MCUBOOT_BUILTIN_KEY @@ -425,7 +458,10 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, #endif /* EXPECTED_SIG_TLV */ struct image_tlv_iter it; uint8_t buf[SIG_BUF_SIZE]; +#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) + int image_hash_valid = 0; uint8_t hash[IMAGE_HASH_SIZE]; +#endif int rc = 0; FIH_DECLARE(fih_rc, FIH_FAILURE); #ifdef MCUBOOT_HW_ROLLBACK_PROT @@ -494,6 +530,7 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } #endif +#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) rc = bootutil_img_hash(enc_state, image_index, hdr, fap, tmp_buf, tmp_buf_sz, hash, seed, seed_len); if (rc) { @@ -503,6 +540,15 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, if (out_hash) { memcpy(out_hash, hash, IMAGE_HASH_SIZE); } +#endif + +#if defined(MCUBOOT_SIGN_PURE) + /* If Pure type signature is expected then it has to be there */ + rc = bootutil_check_for_pure(hdr, fap); + if (rc != 0) { + goto out; + } +#endif rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false); if (rc) { @@ -546,8 +592,10 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } } #endif - - if (type == EXPECTED_HASH_TLV) { + switch(type) { +#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) + case EXPECTED_HASH_TLV: + { /* Verify the image hash. This must always be present. */ if (len != sizeof(hash)) { rc = -1; @@ -565,8 +613,12 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, } image_hash_valid = 1; + break; + } +#endif /* defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) */ #ifdef EXPECTED_KEY_TLV - } else if (type == EXPECTED_KEY_TLV) { + case EXPECTED_KEY_TLV: + { /* * Determine which key we should be checking. */ @@ -591,9 +643,12 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, * The key may not be found, which is acceptable. There * can be multiple signatures, each preceded by a key. */ + break; + } #endif /* EXPECTED_KEY_TLV */ #ifdef EXPECTED_SIG_TLV - } else if (type == EXPECTED_SIG_TLV) { + case EXPECTED_SIG_TLV: + { /* Ignore this signature if it is out of bounds. */ if (key_id < 0 || key_id >= bootutil_key_cnt) { key_id = -1; @@ -607,12 +662,25 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, if (rc) { goto out; } +#ifndef MCUBOOT_SIGN_PURE FIH_CALL(bootutil_verify_sig, valid_signature, hash, sizeof(hash), buf, len, key_id); +#else + /* Directly check signature on the image, by using the mapping of + * a device to memory. The pointer is beginning of image in flash, + * so offset of area, the range is header + image + protected tlvs. + */ + FIH_CALL(bootutil_verify_img, valid_signature, (void *)flash_area_get_off(fap), + hdr->ih_hdr_size + hdr->ih_img_size + hdr->ih_protect_tlv_size, + buf, len, key_id); +#endif key_id = -1; + break; + } #endif /* EXPECTED_SIG_TLV */ #ifdef MCUBOOT_HW_ROLLBACK_PROT - } else if (type == IMAGE_TLV_SEC_CNT) { + case IMAGE_TLV_SEC_CNT: + { /* * Verify the image's security counter. * This must always be present. @@ -647,14 +715,21 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, /* The image's security counter has been successfully verified. */ security_counter_valid = fih_rc; + break; + } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ } } +#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) rc = !image_hash_valid; if (rc) { goto out; } +#elif defined(MCUBOOT_SIGN_PURE) + /* This returns true on EQ, rc is err on non-0 */ + rc = !FIH_EQ(valid_signature, FIH_SUCCESS); +#endif #ifdef EXPECTED_SIG_TLV FIH_SET(fih_rc, valid_signature); #endif diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index d3676e107..94390342f 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -192,6 +192,14 @@ config BOOT_IMG_HASH_ALG_SHA512 endchoice # BOOT_IMG_HASH_ALG +config BOOT_SIGNATURE_TYPE_PURE_ALLOW + bool + help + Hidden option set by configurations that allow Pure variant, + for example ed25519. The pure variant means that image + signature is calculated over entire image instead of hash + of an image. + choice BOOT_SIGNATURE_TYPE prompt "Signature type" default BOOT_SIGNATURE_TYPE_ED25519 if BOARD_NRF54L15PDK_NRF54L15_CPUAPP @@ -242,15 +250,32 @@ endif config BOOT_SIGNATURE_TYPE_ED25519 bool "Edwards curve digital signatures using ed25519" - select BOOT_ENCRYPTION_SUPPORT - select BOOT_IMG_HASH_ALG_SHA256_ALLOW + select BOOT_ENCRYPTION_SUPPORT if !BOOT_SIGNATURE_TYPE_PURE + select BOOT_IMG_HASH_ALG_SHA256_ALLOW if !BOOT_SIGNATURE_TYPE_PURE + # The SHA is used only for key hashing, not for images. select BOOT_IMG_HASH_ALG_SHA512_ALLOW + select BOOT_SIGNATURE_TYPE_PURE_ALLOW help This is ed25519 signature calculated over SHA512 of SHA256 of application image; that is not completely correct approach as the SHA512 should be rather directly calculated over an image. + Select BOOT_SIGNATURE_TYPE_PURE to have a PureEdDSA calculating image + signature directly on image, rather than hash of the image. if BOOT_SIGNATURE_TYPE_ED25519 + +config BOOT_SIGNATURE_TYPE_PURE + bool "Use Pure signature of image" + depends on BOOT_SIGNATURE_TYPE_PURE_ALLOW + help + The Pure signature is calculated directly over image rather than + hash of an image. + This is more secure signature, specifically if hardware can do the + verification without need to share key. + Note that this requires that all slots for which signature is to be + verified need to be accessible through memory address space that + cryptography can access. + choice BOOT_ED25519_IMPLEMENTATION prompt "Ecdsa implementation" default BOOT_ED25519_TINYCRYPT diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index fbd64b5e7..7896e0939 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -147,6 +147,10 @@ #define MCUBOOT_HASH_STORAGE_DIRECTLY #endif +#ifdef CONFIG_BOOT_SIGNATURE_TYPE_PURE +#define MCUBOOT_SIGN_PURE +#endif + #ifdef CONFIG_BOOT_BOOTSTRAP #define MCUBOOT_BOOTSTRAP 1 #endif From 910045d12816fbc1d523232d5cd28e3148ce1f3e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 2 Oct 2024 15:03:50 +0000 Subject: [PATCH 222/238] [nrf noup] There is only one SHA supported at once fixup! [nrf noup] PSA implementation of x25519 and ed25519 verification And fixing typos. Signed-off-by: Dominik Ermel --- boot/bootutil/src/image_ed25519.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 984a58302..07ac36265 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -22,16 +22,15 @@ #include "bootutil_priv.h" #include "bootutil/crypto/common.h" +#include "bootutil/crypto/sha.h" -#define SHA512_LEN 64 -#define SHA256_LEN 32 -#define EDDSA_SIGNAGURE_LENGTH 64 +#define EDDSA_SIGNATURE_LENGTH 64 static const uint8_t ed25519_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x65\x70"; #define NUM_ED25519_BYTES 32 extern int ED25519_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], + const uint8_t signature[EDDSA_SIGNATURE_LENGTH], const uint8_t public_key[NUM_ED25519_BYTES]); /* @@ -82,8 +81,7 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, uint8_t *pubkey; uint8_t *end; - if (!(hlen == SHA512_LEN || hlen == SHA256_LEN) || - slen != EDDSA_SIGNAGURE_LENGTH) { + if (hlen != IMAGE_HASH_SIZE || slen != EDDSA_SIGNATURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } @@ -97,7 +95,7 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, goto out; } - rc = ED25519_verify(hash, hlen, sig, pubkey); + rc = ED25519_verify(hash, IMAGE_HASH_SIZE, sig, pubkey); if (rc == 0) { /* if verify returns 0, there was an error. */ From 4a5d2aebf4ed3bd522ae8e8afcabf39e903ed14c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 2 Oct 2024 15:42:00 +0000 Subject: [PATCH 223/238] [nrf noup] bootutil: Fix typo in identifier fixup! [nrf noup] bootutil: PureEdDSA using ED25519 Signed-off-by: Dominik Ermel --- boot/bootutil/src/image_ed25519.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 07ac36265..40d494bcf 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -118,7 +118,7 @@ bootutil_verify_img(const uint8_t *img, uint32_t size, uint8_t *pubkey; uint8_t *end; - if (slen != EDDSA_SIGNAGURE_LENGTH) { + if (slen != EDDSA_SIGNATURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } From 237b8b98a97103dd27c51cb73fa60841bb9187d0 Mon Sep 17 00:00:00 2001 From: Mateusz Michalek Date: Fri, 9 Aug 2024 12:16:40 +0200 Subject: [PATCH 224/238] [nrf fromlist] scripts: imgtool: compression Adds LZMA2 compression to imgtool. Python lzma library is unable to compress with proper parameters while using "ALONE" container, therefore 2 header bytes are calculated and added to payload by imgtool. Upstream PR: https://github.com/mcu-tools/mcuboot/pull/2038 Signed-off-by: Mateusz Michalek --- scripts/imgtool/image.py | 71 ++++++++++++++++++++++++++++++++---- scripts/imgtool/main.py | 79 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 135 insertions(+), 15 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index 53b19ef1d..1f43ccf82 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -20,7 +20,15 @@ Image signing and management. """ +from . import version as versmod +from .boot_record import create_sw_component_data +import click +import copy +from enum import Enum +import array +from intelhex import IntelHex import hashlib +import array import os.path import struct from enum import Enum @@ -60,6 +68,8 @@ 'NON_BOOTABLE': 0x0000010, 'RAM_LOAD': 0x0000020, 'ROM_FIXED': 0x0000100, + 'COMPRESSED_LZMA1': 0x0000200, + 'COMPRESSED_LZMA2': 0x0000400, } TLV_VALUES = { @@ -79,6 +89,9 @@ 'DEPENDENCY': 0x40, 'SEC_CNT': 0x50, 'BOOT_RECORD': 0x60, + 'DECOMP_SIZE': 0x70, + 'DECOMP_SHA': 0x71, + 'DECOMP_SIGNATURE': 0x72, } TLV_SIZE = 4 @@ -237,6 +250,9 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, if load_addr and rom_fixed: raise click.UsageError("Can not set rom_fixed and load_addr at the same time") + self.image_hash = None + self.image_size = None + self.signature = None self.version = version or versmod.decode_version("0") self.header_size = header_size self.pad_header = pad_header @@ -252,6 +268,7 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, self.rom_fixed = rom_fixed self.erased_val = 0xff if erased_val is None else int(erased_val, 0) self.payload = [] + self.infile_data = [] self.enckey = None self.save_enctlv = save_enctlv self.enctlv_len = 0 @@ -300,19 +317,39 @@ def __repr__(self): self.__class__.__name__, len(self.payload)) - def load(self, path): + def load(self, path, compression_header=None): """Load an image from a given file""" ext = os.path.splitext(path)[1][1:].lower() try: if ext == INTEL_HEX_EXT: ih = IntelHex(path) - self.payload = ih.tobinarray() + self.infile_data = ih.tobinarray() + self.payload = copy.copy(self.infile_data) self.base_addr = ih.minaddr() else: with open(path, 'rb') as f: - self.payload = f.read() + self.infile_data = f.read() + self.payload = copy.copy(self.infile_data) + if compression_header is not None: + self.payload = compression_header + self.payload except FileNotFoundError: raise click.UsageError("Input file not found") + self.image_size = len(self.payload) + + # Add the image header if needed. + if self.pad_header and self.header_size > 0: + if self.base_addr: + # Adjust base_addr for new header + self.base_addr -= self.header_size + self.payload = bytes([self.erased_val] * self.header_size) + \ + self.payload + + self.check_header() + + def load_compressed(self, data, compression_header): + """Load an image from buffer""" + self.payload = compression_header + data + self.image_size = len(self.payload) # Add the image header if needed. if self.pad_header and self.header_size > 0: @@ -407,7 +444,8 @@ def ecies_hkdf(self, enckey, plainkey): return cipherkey, ciphermac, pubk def create(self, key, public_key_format, enckey, dependencies=None, - sw_type=None, custom_tlvs=None, encrypt_keylen=128, clear=False, + sw_type=None, custom_tlvs=None, compression_tlvs=None, + compression_type=None, encrypt_keylen=128, clear=False, fixed_sig=None, pub_key=None, vector_to_sign=None, user_sha='auto'): self.enckey = enckey @@ -470,6 +508,9 @@ def create(self, key, public_key_format, enckey, dependencies=None, dependencies_num = len(dependencies[DEP_IMAGES_KEY]) protected_tlv_size += (dependencies_num * 16) + if compression_tlvs is not None: + for value in compression_tlvs.values(): + protected_tlv_size += TLV_SIZE + len(value) if custom_tlvs is not None: for value in custom_tlvs.values(): protected_tlv_size += TLV_SIZE + len(value) @@ -491,11 +532,15 @@ def create(self, key, public_key_format, enckey, dependencies=None, else: self.payload.extend(pad) + compression_flags = 0x0 + if compression_tlvs is not None: + if compression_type == "lzma2": + compression_flags = IMAGE_F['COMPRESSED_LZMA2'] # This adds the header to the payload as well if encrypt_keylen == 256: - self.add_header(enckey, protected_tlv_size, 256) + self.add_header(enckey, protected_tlv_size, compression_flags, 256) else: - self.add_header(enckey, protected_tlv_size) + self.add_header(enckey, protected_tlv_size, compression_flags) prot_tlv = TLV(self.endian, TLV_PROT_INFO_MAGIC) @@ -525,6 +570,9 @@ def create(self, key, public_key_format, enckey, dependencies=None, ) prot_tlv.add('DEPENDENCY', payload) + if compression_tlvs is not None: + for tag, value in compression_tlvs.items(): + prot_tlv.add(tag, value) if custom_tlvs is not None: for tag, value in custom_tlvs.items(): prot_tlv.add(tag, value) @@ -543,6 +591,7 @@ def create(self, key, public_key_format, enckey, dependencies=None, digest = sha.digest() message = digest; tlv.add(hash_tlv, digest) + self.image_hash = digest if vector_to_sign == 'payload': # Stop amending data to the image @@ -622,10 +671,16 @@ def create(self, key, public_key_format, enckey, dependencies=None, self.check_trailer() + def get_struct_endian(self): + return STRUCT_ENDIAN_DICT[self.endian] + def get_signature(self): return self.signature - def add_header(self, enckey, protected_tlv_size, aes_length=128): + def get_infile_data(self): + return self.infile_data + + def add_header(self, enckey, protected_tlv_size, compression_flags, aes_length=128): """Install the image header.""" flags = 0 @@ -663,7 +718,7 @@ def add_header(self, enckey, protected_tlv_size, aes_length=128): protected_tlv_size, # TLV Info header + # Protected TLVs len(self.payload) - self.header_size, # ImageSz - flags, + flags | compression_flags, self.version.major, self.version.minor or 0, self.version.revision or 0, diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index 848fd3110..9e91582b9 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -22,6 +22,10 @@ import getpass import imgtool.keys as keys import sys +import struct +import os +import lzma +import hashlib import base64 from imgtool import image, imgtool_version from imgtool.version import decode_version @@ -29,6 +33,13 @@ from .keys import ( RSAUsageError, ECDSAUsageError, Ed25519UsageError, X25519UsageError) +comp_default_dictsize=131072 +comp_default_pb=2 +comp_default_lc=3 +comp_default_lp=1 +comp_default_preset=9 + + MIN_PYTHON_VERSION = (3, 6) if sys.version_info < MIN_PYTHON_VERSION: sys.exit("Python %s.%s or newer is required by imgtool." @@ -300,6 +311,14 @@ def get_dependencies(ctx, param, value): dependencies[image.DEP_VERSIONS_KEY] = versions return dependencies +def create_lzma2_header(dictsize, pb, lc, lp): + header = bytearray() + for i in range(0, 40): + if dictsize <= ((2 | ((i) & 1)) << int((i) / 2 + 11)): + header.append(i) + break + header.append( ( pb * 5 + lp) * 9 + lc) + return header class BasedIntParamType(click.ParamType): name = 'integer' @@ -343,6 +362,11 @@ def convert(self, value, param, ctx): type=click.Choice(['128', '256']), help='When encrypting the image using AES, select a 128 bit or ' '256 bit key len.') +@click.option('--compression', default='disabled', + type=click.Choice(['disabled', 'lzma2']), + help='Enable image compression using specified type. ' + 'Will fall back without image compression automatically ' + 'if the compression increases the image size.') @click.option('-c', '--clear', required=False, is_flag=True, default=False, help='Output a non-encrypted image with encryption capabilities,' 'so it can be installed in the primary slot, and encrypted ' @@ -414,10 +438,11 @@ def convert(self, value, param, ctx): .hex extension, otherwise binary format is used''') def sign(key, public_key_format, align, version, pad_sig, header_size, pad_header, slot_size, pad, confirm, max_sectors, overwrite_only, - endian, encrypt_keylen, encrypt, infile, outfile, dependencies, - load_addr, hex_addr, erased_val, save_enctlv, security_counter, - boot_record, custom_tlv, rom_fixed, max_align, clear, fix_sig, - fix_sig_pubkey, sig_out, user_sha, vector_to_sign, non_bootable): + endian, encrypt_keylen, encrypt, compression, infile, outfile, + dependencies, load_addr, hex_addr, erased_val, save_enctlv, + security_counter, boot_record, custom_tlv, rom_fixed, max_align, + clear, fix_sig, fix_sig_pubkey, sig_out, user_sha, vector_to_sign, + non_bootable): if confirm: # Confirmed but non-padded images don't make much sense, because @@ -431,6 +456,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, erased_val=erased_val, save_enctlv=save_enctlv, security_counter=security_counter, max_align=max_align, non_bootable=non_bootable) + compression_tlvs = {} img.load(infile) key = load_key(key) if key else None enckey = load_key(encrypt) if encrypt else None @@ -484,10 +510,49 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, } img.create(key, public_key_format, enckey, dependencies, boot_record, - custom_tlvs, int(encrypt_keylen), clear, baked_signature, - pub_key, vector_to_sign, user_sha) + custom_tlvs, compression_tlvs, int(encrypt_keylen), clear, + baked_signature, pub_key, vector_to_sign, user_sha) + + if compression == "lzma2" : + compressed_img = image.Image(version=decode_version(version), + header_size=header_size, pad_header=pad_header, + pad=pad, confirm=confirm, align=int(align), + slot_size=slot_size, max_sectors=max_sectors, + overwrite_only=overwrite_only, endian=endian, + load_addr=load_addr, rom_fixed=rom_fixed, + erased_val=erased_val, save_enctlv=save_enctlv, + security_counter=security_counter, max_align=max_align) + compression_filters = [ + {"id": lzma.FILTER_LZMA2, "preset": comp_default_preset, + "dict_size": comp_default_dictsize, "lp": comp_default_lp, + "lc": comp_default_lc} + ] + compressed_data = lzma.compress(img.get_infile_data(),filters=compression_filters, + format=lzma.FORMAT_RAW) + uncompressed_size = len(img.get_infile_data()) + compressed_size = len(compressed_data) + print("compressed image size:", compressed_size, + "bytes\noriginal image size:", uncompressed_size, "bytes") + compression_tlvs["DECOMP_SIZE"] = struct.pack( + img.get_struct_endian() + 'L', img.image_size) + compression_tlvs["DECOMP_SHA"] = img.image_hash + compression_tlvs_size = len(compression_tlvs["DECOMP_SIZE"]) + compression_tlvs_size += len(compression_tlvs["DECOMP_SHA"]) + if img.get_signature() is not None and img.get_signature() != "" : + compression_tlvs["DECOMP_SIGNATURE"] = img.get_signature() + compression_tlvs_size += len(compression_tlvs["DECOMP_SIGNATURE"]) + if (compressed_size + compression_tlvs_size) < uncompressed_size: + compression_header = create_lzma2_header( + dictsize = comp_default_dictsize, pb = comp_default_pb, + lc = comp_default_lc, lp = comp_default_lp) + compressed_img.load_compressed(compressed_data, compression_header) + compressed_img.base_addr = img.base_addr + compressed_img.create(key, public_key_format, enckey, + dependencies, boot_record, custom_tlvs, compression_tlvs, + compression, int(encrypt_keylen), clear, baked_signature, + pub_key, vector_to_sign) + img = compressed_img img.save(outfile, hex_addr) - if sig_out is not None: new_signature = img.get_signature() save_signature(sig_out, new_signature) From f3a288d64d48d576b40568c05f63659d0aba1eba Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 2 Oct 2024 14:05:32 +0100 Subject: [PATCH 225/238] [nrf noup] boot: zephyr: kconfig: Select PM_USE_CONFIG_SRAM_SIZE when needed fixup! [nrf noup] zephyr: Add support for compressed image updates Selects this Kconfig when compression is enabled for nrf54l15 Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 94390342f..8b66ad96a 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -919,6 +919,7 @@ if BOOT_DECOMPRESSION_SUPPORT menuconfig BOOT_DECOMPRESSION bool "Decompression" select NRF_COMPRESS_CLEANUP + select PM_USE_CONFIG_SRAM_SIZE if SOC_NRF54L15_CPUAPP help If enabled, will include support for compressed images being loaded to the secondary slot which then get decompressed into the primary slot. This mode allows the secondary slot to From c020cd05e42d80953c217582bac2329cd64fa407 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 1 Oct 2024 15:39:31 +0000 Subject: [PATCH 226/238] [nrf noup] Add missing selection of MBEDTLS_PSA_CRYPTO_C fixup! [nrf noup] PSA configuration required changes Signed-off-by: Dominik Ermel --- boot/zephyr/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 8b66ad96a..ca266af01 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -32,6 +32,7 @@ config BOOT_USE_PSA_CRYPTO default y if NRF_SECURITY # This is counter intuitive but that is how PSA heap is enabled. select MBEDTLS_ENABLE_HEAP + select MBEDTLS_PSA_CRYPTO_C help Hidden option set if using PSA crypt for cryptography functionality From 12e9928b48a081a74a8b0688e6c310315de12f88 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 19 Sep 2024 14:32:37 +0200 Subject: [PATCH 227/238] [nrf noup] boot/zephyr/Kconfig: conditionally disable BOOT_MAX_IMG_SECTORS_AUTO Automatic calculation are based on DTS data which are no the right source on partition layout in case Partition manager does the partitioning. Signed-off-by: Andrzej Puzdrowski --- boot/zephyr/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index ca266af01..9022a0ce5 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -558,7 +558,7 @@ config BOOT_ENCRYPTION_KEY_FILE config BOOT_MAX_IMG_SECTORS_AUTO bool "Calculate maximum sectors automatically" - default y + default y if !PARTITION_MANAGER_ENABLED help If this option is enabled then the maximum number of supported sectors per image will be calculated automatically from the flash erase sizes and size of each partition for From e295db1208183f0fa8ddbe4fa243014fe676bbb5 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Tue, 24 Sep 2024 16:35:08 +0200 Subject: [PATCH 228/238] [nrf fromlist] zephyr/Kconfig.serial_recovery: limit Slot info command BOOT_SERIAL_IMG_GRP_SLOT_INFO should be not available for direct-xip and ram-load modes. Upstream PR: https://github.com/mcu-tools/mcuboot/pull/2073 Signed-off-by: Andrzej Puzdrowski --- boot/zephyr/Kconfig.serial_recovery | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig.serial_recovery b/boot/zephyr/Kconfig.serial_recovery index 7ed9a7d9c..4d31844c1 100644 --- a/boot/zephyr/Kconfig.serial_recovery +++ b/boot/zephyr/Kconfig.serial_recovery @@ -204,7 +204,8 @@ config BOOT_SERIAL_IMG_GRP_IMAGE_STATE config BOOT_SERIAL_IMG_GRP_SLOT_INFO bool "Slot info" - default y if UPDATEABLE_IMAGE_NUMBER > 1 + depends on !BOOT_DIRECT_XIP && !BOOT_RAM_LOAD + default y if (UPDATEABLE_IMAGE_NUMBER > 1) help If y, will include the slot info command which lists what available slots there are in the system. From d44d7bcc4b825a087b95422c725f774aa726d6ec Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 25 Sep 2024 07:47:08 +0100 Subject: [PATCH 229/238] [nrf fromtree] boot: bootutil: loader: Fix slot info for directXIP/RAM load Fixes an issue when either of these modes is used with serial recovery slot info enabled Signed-off-by: Jamie McCrae (cherry picked from commit 30109df32a65840d593e8aef2e2186d5337196f3) --- boot/bootutil/src/loader.c | 149 ++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 61 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 7af3e42c0..505b6a271 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -330,6 +330,93 @@ boot_version_cmp(const struct image_version *ver1, } #endif +#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \ +defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO) +#if !defined(__BOOTSIM__) +static void boot_get_sector_buffers(struct sector_buffer_t *buffers) +{ + /* The array of slot sectors are defined here (as opposed to file scope) so + * that they don't get allocated for non-boot-loader apps. This is + * necessary because the gcc option "-fdata-sections" doesn't seem to have + * any effect in older gcc versions (e.g., 4.8.4). + */ + static boot_sector_t primary_slot_sectors[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS]; + static boot_sector_t secondary_slot_sectors[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS]; +#if MCUBOOT_SWAP_USING_SCRATCH + static boot_sector_t scratch_sectors[BOOT_MAX_IMG_SECTORS]; +#endif + + buffers->primary = (boot_sector_t *)&primary_slot_sectors; + buffers->secondary = (boot_sector_t *)&secondary_slot_sectors; +#if MCUBOOT_SWAP_USING_SCRATCH + buffers->scratch = (boot_sector_t *)&scratch_sectors; +#endif +} +#endif + +static int +boot_initialize_area(struct boot_loader_state *state, int flash_area) +{ + uint32_t num_sectors = BOOT_MAX_IMG_SECTORS; + boot_sector_t *out_sectors; + uint32_t *out_num_sectors; + int rc; + + num_sectors = BOOT_MAX_IMG_SECTORS; + + if (flash_area == FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state))) { + out_sectors = BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors; + out_num_sectors = &BOOT_IMG(state, BOOT_PRIMARY_SLOT).num_sectors; + } else if (flash_area == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) { + out_sectors = BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors; + out_num_sectors = &BOOT_IMG(state, BOOT_SECONDARY_SLOT).num_sectors; +#if MCUBOOT_SWAP_USING_SCRATCH + } else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) { + out_sectors = state->scratch.sectors; + out_num_sectors = &state->scratch.num_sectors; +#endif + } else { + return BOOT_EFLASH; + } + +#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS + rc = flash_area_get_sectors(flash_area, &num_sectors, out_sectors); +#else + _Static_assert(sizeof(int) <= sizeof(uint32_t), "Fix needed"); + rc = flash_area_to_sectors(flash_area, (int *)&num_sectors, out_sectors); +#endif /* defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */ + if (rc != 0) { + return rc; + } + *out_num_sectors = num_sectors; + return 0; +} +#endif + +#if defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO) +static int +boot_read_sectors_recovery(struct boot_loader_state *state) +{ + uint8_t image_index; + int rc; + + image_index = BOOT_CURR_IMG(state); + + rc = boot_initialize_area(state, FLASH_AREA_IMAGE_PRIMARY(image_index)); + if (rc != 0) { + return BOOT_EFLASH; + } + + rc = boot_initialize_area(state, FLASH_AREA_IMAGE_SECONDARY(image_index)); + if (rc != 0) { + /* We need to differentiate from the primary image issue */ + return BOOT_EFLASH_SEC; + } + + return 0; +} +#endif + #if (BOOT_IMAGE_NUMBER > 1) @@ -690,44 +777,6 @@ boot_write_sz(struct boot_loader_state *state) return elem_sz; } -static int -boot_initialize_area(struct boot_loader_state *state, int flash_area) -{ - uint32_t num_sectors = BOOT_MAX_IMG_SECTORS; - boot_sector_t *out_sectors; - uint32_t *out_num_sectors; - int rc; - - num_sectors = BOOT_MAX_IMG_SECTORS; - - if (flash_area == FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state))) { - out_sectors = BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors; - out_num_sectors = &BOOT_IMG(state, BOOT_PRIMARY_SLOT).num_sectors; - } else if (flash_area == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) { - out_sectors = BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors; - out_num_sectors = &BOOT_IMG(state, BOOT_SECONDARY_SLOT).num_sectors; -#if MCUBOOT_SWAP_USING_SCRATCH - } else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) { - out_sectors = state->scratch.sectors; - out_num_sectors = &state->scratch.num_sectors; -#endif - } else { - return BOOT_EFLASH; - } - -#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS - rc = flash_area_get_sectors(flash_area, &num_sectors, out_sectors); -#else - _Static_assert(sizeof(int) <= sizeof(uint32_t), "Fix needed"); - rc = flash_area_to_sectors(flash_area, (int *)&num_sectors, out_sectors); -#endif /* defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */ - if (rc != 0) { - return rc; - } - *out_num_sectors = num_sectors; - return 0; -} - /** * Determines the sector layout of both image slots and the scratch area. * This information is necessary for calculating the number of bytes to erase @@ -2496,28 +2545,6 @@ check_downgrade_prevention(struct boot_loader_state *state) #endif } -#if !defined(__BOOTSIM__) -static void boot_get_sector_buffers(struct sector_buffer_t *buffers) -{ - /* The array of slot sectors are defined here (as opposed to file scope) so - * that they don't get allocated for non-boot-loader apps. This is - * necessary because the gcc option "-fdata-sections" doesn't seem to have - * any effect in older gcc versions (e.g., 4.8.4). - */ - static boot_sector_t primary_slot_sectors[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS]; - static boot_sector_t secondary_slot_sectors[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS]; -#if MCUBOOT_SWAP_USING_SCRATCH - static boot_sector_t scratch_sectors[BOOT_MAX_IMG_SECTORS]; -#endif - - buffers->primary = (boot_sector_t *)&primary_slot_sectors; - buffers->secondary = (boot_sector_t *)&secondary_slot_sectors; -#if MCUBOOT_SWAP_USING_SCRATCH - buffers->scratch = (boot_sector_t *)&scratch_sectors; -#endif -} -#endif - fih_ret context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) { @@ -3850,7 +3877,7 @@ static void boot_fetch_slot_state_sizes(void) #endif /* Determine the sector layout of the image slots and scratch area. */ - rc = boot_read_sectors(&boot_data); + rc = boot_read_sectors_recovery(&boot_data); if (rc == 0) { max_size = app_max_size(&boot_data); From 22adc04fc4b35a6ee477675c8a33e038a98258de Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 27 Sep 2024 13:31:08 +0100 Subject: [PATCH 230/238] [nrf fromtree] boot: bootutil: loader: Fix issue with using pointers Fixes an issue whereby static buffers were changed into pointers, whereby they are then assumed to be the size of a pointer rather than the size of the actual buffers Signed-off-by: Jamie McCrae (cherry picked from commit 3a195f2207d5eadf45a5c989a870e91aff020d86) Signed-off-by: Dominik Ermel --- boot/bootutil/src/loader.c | 55 ++++++++++---------------------------- 1 file changed, 14 insertions(+), 41 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 505b6a271..53f40c33a 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -87,17 +87,22 @@ static bool owner_nsib[BOOT_IMAGE_NUMBER] = {false}; static struct image_max_size image_max_sizes[BOOT_IMAGE_NUMBER] = {0}; #endif +#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \ +defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO) #if !defined(__BOOTSIM__) /* Used for holding static buffers in multiple functions to work around issues * in older versions of gcc (e.g. 4.8.4) */ struct sector_buffer_t { - boot_sector_t *primary; - boot_sector_t *secondary; + boot_sector_t primary[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS]; + boot_sector_t secondary[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS]; #if MCUBOOT_SWAP_USING_SCRATCH - boot_sector_t *scratch; + boot_sector_t scratch[BOOT_MAX_IMG_SECTORS]; #endif }; + +static struct sector_buffer_t sector_buffers; +#endif #endif #if (BOOT_IMAGE_NUMBER > 1) @@ -332,28 +337,6 @@ boot_version_cmp(const struct image_version *ver1, #if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \ defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO) -#if !defined(__BOOTSIM__) -static void boot_get_sector_buffers(struct sector_buffer_t *buffers) -{ - /* The array of slot sectors are defined here (as opposed to file scope) so - * that they don't get allocated for non-boot-loader apps. This is - * necessary because the gcc option "-fdata-sections" doesn't seem to have - * any effect in older gcc versions (e.g., 4.8.4). - */ - static boot_sector_t primary_slot_sectors[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS]; - static boot_sector_t secondary_slot_sectors[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS]; -#if MCUBOOT_SWAP_USING_SCRATCH - static boot_sector_t scratch_sectors[BOOT_MAX_IMG_SECTORS]; -#endif - - buffers->primary = (boot_sector_t *)&primary_slot_sectors; - buffers->secondary = (boot_sector_t *)&secondary_slot_sectors; -#if MCUBOOT_SWAP_USING_SCRATCH - buffers->scratch = (boot_sector_t *)&scratch_sectors; -#endif -} -#endif - static int boot_initialize_area(struct boot_loader_state *state, int flash_area) { @@ -2550,9 +2533,6 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) { size_t slot; struct boot_status bs; -#if !defined(__BOOTSIM__) - struct sector_buffer_t sector_buffers; -#endif int rc = -1; FIH_DECLARE(fih_rc, FIH_FAILURE); int fa_id; @@ -2579,10 +2559,6 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) (void)has_upgrade; #endif -#if !defined(__BOOTSIM__) - boot_get_sector_buffers(§or_buffers); -#endif - /* Iterate over all the images. By the end of the loop the swap type has * to be determined for each image and all aborted swaps have to be * completed. @@ -2605,9 +2581,9 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) #if !defined(__BOOTSIM__) BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors = - §or_buffers.primary[image_index]; + sector_buffers.primary[image_index]; BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors = - §or_buffers.secondary[image_index]; + sector_buffers.secondary[image_index]; #if MCUBOOT_SWAP_USING_SCRATCH state->scratch.sectors = sector_buffers.scratch; #endif @@ -3827,30 +3803,27 @@ void boot_state_clear(struct boot_loader_state *state) #if defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO) /** * Reads image data to find out the maximum application sizes. Only needs to - * be called in serial recovery mode, as the state informatio is unpopulated + * be called in serial recovery mode, as the state information is unpopulated * at that time */ static void boot_fetch_slot_state_sizes(void) { - struct sector_buffer_t sector_buffers; size_t slot; int rc = -1; int fa_id; int image_index; - boot_get_sector_buffers(§or_buffers); - IMAGES_ITER(BOOT_CURR_IMG(&boot_data)) { int max_size = 0; image_index = BOOT_CURR_IMG(&boot_data); BOOT_IMG(&boot_data, BOOT_PRIMARY_SLOT).sectors = - §or_buffers.primary[image_index]; + sector_buffers.primary[image_index]; BOOT_IMG(&boot_data, BOOT_SECONDARY_SLOT).sectors = - §or_buffers.secondary[image_index]; + sector_buffers.secondary[image_index]; #if MCUBOOT_SWAP_USING_SCRATCH - boot_data.scratch.sectors = sector_buffers.scratch;; + boot_data.scratch.sectors = sector_buffers.scratch; #endif /* Open primary and secondary image areas for the duration From 10f3dbe511f9e480e9114de44819208bcc4237de Mon Sep 17 00:00:00 2001 From: Mateusz Michalek Date: Fri, 9 Aug 2024 12:16:40 +0200 Subject: [PATCH 231/238] [nrf fromtree] scripts: imgtool: compression Adds LZMA2 compression to imgtool. Python lzma library is unable to compress with proper parameters while using "ALONE" container, therefore 2 header bytes are calculated and added to payload by imgtool. Signed-off-by: Mateusz Michalek (cherry picked from commit 35c9291fcafafe8608722e0ec3c801178884f0ef) --- scripts/imgtool/image.py | 4 +--- scripts/imgtool/main.py | 10 +++++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index 1f43ccf82..10de2a33f 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -317,7 +317,7 @@ def __repr__(self): self.__class__.__name__, len(self.payload)) - def load(self, path, compression_header=None): + def load(self, path): """Load an image from a given file""" ext = os.path.splitext(path)[1][1:].lower() try: @@ -330,8 +330,6 @@ def load(self, path, compression_header=None): with open(path, 'rb') as f: self.infile_data = f.read() self.payload = copy.copy(self.infile_data) - if compression_header is not None: - self.payload = compression_header + self.payload except FileNotFoundError: raise click.UsageError("Input file not found") self.image_size = len(self.payload) diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index 9e91582b9..03bb565c5 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -513,7 +513,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, custom_tlvs, compression_tlvs, int(encrypt_keylen), clear, baked_signature, pub_key, vector_to_sign, user_sha) - if compression == "lzma2" : + if compression == "lzma2": compressed_img = image.Image(version=decode_version(version), header_size=header_size, pad_header=pad_header, pad=pad, confirm=confirm, align=int(align), @@ -525,20 +525,20 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, compression_filters = [ {"id": lzma.FILTER_LZMA2, "preset": comp_default_preset, "dict_size": comp_default_dictsize, "lp": comp_default_lp, - "lc": comp_default_lc} + "lc": comp_default_lc} ] compressed_data = lzma.compress(img.get_infile_data(),filters=compression_filters, format=lzma.FORMAT_RAW) uncompressed_size = len(img.get_infile_data()) compressed_size = len(compressed_data) - print("compressed image size:", compressed_size, - "bytes\noriginal image size:", uncompressed_size, "bytes") + print(f"compressed image size: {compressed_size} bytes") + print(f"original image size: {uncompressed_size} bytes") compression_tlvs["DECOMP_SIZE"] = struct.pack( img.get_struct_endian() + 'L', img.image_size) compression_tlvs["DECOMP_SHA"] = img.image_hash compression_tlvs_size = len(compression_tlvs["DECOMP_SIZE"]) compression_tlvs_size += len(compression_tlvs["DECOMP_SHA"]) - if img.get_signature() is not None and img.get_signature() != "" : + if img.get_signature(): compression_tlvs["DECOMP_SIGNATURE"] = img.get_signature() compression_tlvs_size += len(compression_tlvs["DECOMP_SIGNATURE"]) if (compressed_size + compression_tlvs_size) < uncompressed_size: From b245ccdbbd131cc3788f50eef5cc0410ad34a4de Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 7 Oct 2024 08:40:16 +0100 Subject: [PATCH 232/238] [nrf noup] zephyr: Fix compressed image support fixup! [nrf noup] zephyr: Add support for compressed image updates Fixes some issues with compressed image update support Signed-off-by: Jamie McCrae --- boot/bootutil/src/image_validate.c | 6 ++++-- boot/zephyr/decompression.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 1ba0f7b23..600d25a1a 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -508,14 +508,16 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, found_flag = &found_decompressed_sha; break; case IMAGE_TLV_DECOMP_SIGNATURE: - expected_size = SIG_BUF_SIZE; found_flag = &found_decompressed_signature; break; default: continue; }; - if (len != expected_size) { + if (type == IMAGE_TLV_DECOMP_SIGNATURE && !EXPECTED_SIG_LEN(len)) { + rc = -1; + goto out; + } else if (type != IMAGE_TLV_DECOMP_SIGNATURE && len != expected_size) { rc = -1; goto out; } diff --git a/boot/zephyr/decompression.c b/boot/zephyr/decompression.c index 5d491adcf..b44caa8a2 100644 --- a/boot/zephyr/decompression.c +++ b/boot/zephyr/decompression.c @@ -1027,7 +1027,7 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl /* Check if we have unwritten data buffered up and, if so, write it out */ if (decomp_buf_size > 0) { - uint32_t write_padding_size = decomp_buf_size % write_alignment; + uint32_t write_padding_size = write_alignment - (decomp_buf_size % write_alignment); /* Check if additional write padding should be applied to meet the minimum write size */ if (write_padding_size) { From 8c814cbbae3036d7f5778f32abeade142ad8e30e Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 7 Oct 2024 08:37:48 +0100 Subject: [PATCH 233/238] [nrf fromlist] boot: bootutil: swap_scratch: Fix compressed image sector size check Fixes an issue with compressed update support whereby it would wrong continue to check all sector sizes and error due to the sector sizes of the secondary slot being 0 until overflow Upstream PR: https://github.com/mcu-tools/mcuboot/pull/2085 Signed-off-by: Jamie McCrae --- boot/bootutil/src/swap_scratch.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index 08dffb186..66dca83e9 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -203,7 +203,17 @@ boot_slots_compatible(struct boot_loader_state *state) smaller = 1; i++; } else { - sz1 += boot_img_sector_size(state, BOOT_SECONDARY_SLOT, j); + size_t sector_size = boot_img_sector_size(state, BOOT_SECONDARY_SLOT, j); + +#ifdef MCUBOOT_DECOMPRESS_IMAGES + if (sector_size == 0) { + /* Since this supports decompressed images, we can safely exit if slot1 is + * smaller than slot0. + */ + break; + } +#endif + sz1 += sector_size; /* Guarantee that multiple sectors of the primary slot * fit into the secondary slot. */ From 0ea935a76ad1b7bbcd58521b7ecbd5e07dd54283 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 2 Sep 2024 11:20:00 +0100 Subject: [PATCH 234/238] [nrf noup] zephyr: Add support for ARM thumb filter Adds support for ARM thumb filter usage for compressed firmware updates Signed-off-by: Jamie McCrae --- boot/zephyr/decompression.c | 179 +++++++++++++++++++++++++----------- 1 file changed, 127 insertions(+), 52 deletions(-) diff --git a/boot/zephyr/decompression.c b/boot/zephyr/decompression.c index b44caa8a2..f958a0609 100644 --- a/boot/zephyr/decompression.c +++ b/boot/zephyr/decompression.c @@ -87,13 +87,22 @@ bool boot_is_compressed_header_valid(const struct image_header *hdr, const struc if (size >= size_check) { BOOT_LOG_ERR("Compressed image too large, decompressed image size: 0x%x, slot size: 0x%x", size, size_check); - return false; } return true; } +static bool is_compression_object_valid(struct nrf_compress_implementation *compression) +{ + if (compression == NULL || compression->init == NULL || compression->deinit == NULL || + compression->decompress_bytes_needed == NULL || compression->decompress == NULL) { + return false; + } + + return true; +} + int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index, struct image_header *hdr, const struct flash_area *fap, uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result, @@ -104,7 +113,8 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index uint32_t write_pos = 0; uint32_t protected_tlv_size = 0; uint32_t decompressed_image_size; - struct nrf_compress_implementation *compression = NULL; + struct nrf_compress_implementation *compression_lzma = NULL; + struct nrf_compress_implementation *compression_arm_thumb = NULL; TARGET_STATIC struct image_header modified_hdr; bootutil_sha_context sha_ctx; uint8_t flash_erased_value; @@ -122,27 +132,26 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index */ BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); rc = BOOT_EBADIMAGE; - goto finish_without_clean; } - compression = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + compression_lzma = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + compression_arm_thumb = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_ARM_THUMB); - if (compression == NULL || compression->init == NULL || compression->deinit == NULL || - compression->decompress_bytes_needed == NULL || compression->decompress == NULL) { + if (!is_compression_object_valid(compression_lzma) || + !is_compression_object_valid(compression_arm_thumb)) { /* Compression library missing or missing required function pointer */ BOOT_LOG_ERR("Decompression library fatal error"); rc = BOOT_EBADSTATUS; - goto finish_without_clean; } - rc = compression->init(NULL); + rc = compression_lzma->init(NULL); + rc = compression_arm_thumb->init(NULL); if (rc) { BOOT_LOG_ERR("Decompression library fatal error"); rc = BOOT_EBADSTATUS; - goto finish_without_clean; } @@ -157,7 +166,6 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index if (rc) { BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); rc = BOOT_EBADIMAGE; - goto finish; } @@ -172,7 +180,6 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index if (rc) { BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); rc = BOOT_EBADIMAGE; - goto finish; } @@ -211,7 +218,6 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", (hdr->ih_hdr_size + read_pos), copy_size, fap->fa_id, rc); rc = BOOT_EFLASH; - goto finish; } @@ -225,7 +231,7 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index uint32_t chunk_size; bool last_packet = false; - chunk_size = compression->decompress_bytes_needed(NULL); + chunk_size = compression_lzma->decompress_bytes_needed(NULL); if (chunk_size > (copy_size - tmp_off)) { chunk_size = (copy_size - tmp_off); @@ -235,13 +241,12 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index last_packet = true; } - rc = compression->decompress(NULL, &tmp_buf[tmp_off], chunk_size, last_packet, &offset, - &output, &output_size); + rc = compression_lzma->decompress(NULL, &tmp_buf[tmp_off], chunk_size, last_packet, + &offset, &output, &output_size); if (rc) { BOOT_LOG_ERR("Decompression error: %d", rc); rc = BOOT_EBADSTATUS; - goto finish; } @@ -251,7 +256,6 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index BOOT_LOG_ERR("Decompressed image larger than claimed TLV size, at least: %d", write_pos); rc = BOOT_EBADIMAGE; - goto finish; } @@ -260,7 +264,6 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index /* Last packet and we still have no output, this is a faulty update */ BOOT_LOG_ERR("All compressed data consumed without any output, image not valid"); rc = BOOT_EBADIMAGE; - goto finish; } @@ -271,7 +274,6 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index if (offset_zero_check >= OFFSET_ZERO_CHECK_TIMES) { BOOT_LOG_ERR("Decompression system returning no output data, image not valid"); rc = BOOT_EBADIMAGE; - goto finish; } @@ -282,8 +284,60 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index offset_zero_check = 0; } + /* Copy data to secondary buffer for calculating hash */ if (output_size > 0) { - bootutil_sha_update(&sha_ctx, output, output_size); + if (hdr->ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT) { + /* Run this through the ARM thumb filter */ + uint32_t offset_arm_thumb = 0; + uint8_t *output_arm_thumb = NULL; + uint32_t processed_size = 0; + uint32_t output_size_arm_thumb = 0; + uint32_t output_size_arm_thumb_total = 0; + + while (processed_size < output_size) { + uint32_t current_size = output_size - processed_size; + bool arm_thumb_last_packet = false; + + if (current_size > CONFIG_NRF_COMPRESS_CHUNK_SIZE) { + current_size = CONFIG_NRF_COMPRESS_CHUNK_SIZE; + } + + if (last_packet && (processed_size + current_size) == + output_size) { + arm_thumb_last_packet = true; + } + + rc = compression_arm_thumb->decompress(NULL, &output[processed_size], + current_size, arm_thumb_last_packet, + &offset_arm_thumb, + &output_arm_thumb, + &output_size_arm_thumb); + + if (rc) { + BOOT_LOG_ERR("Decompression error: %d", rc); + rc = BOOT_EBADSTATUS; + goto finish; + } else if (current_size != offset_arm_thumb) { + BOOT_LOG_ERR("Decompression expected offset mismatch: %d vs %d", + current_size, offset_arm_thumb); + rc = BOOT_EBADSTATUS; + goto finish; + } + + bootutil_sha_update(&sha_ctx, output_arm_thumb, output_size_arm_thumb); + output_size_arm_thumb_total += output_size_arm_thumb; + processed_size += current_size; + } + + if (output_size != output_size_arm_thumb_total) { + BOOT_LOG_ERR("Decompression expected output_size mismatch: %d vs %d", + output_size, output_size_arm_thumb); + rc = BOOT_EBADSTATUS; + goto finish; + } + } else { + bootutil_sha_update(&sha_ctx, output, output_size); + } } tmp_off += offset; @@ -302,7 +356,8 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index finish: /* Clean up decompression system */ - (void)compression->deinit(NULL); + (void)compression_lzma->deinit(NULL); + (void)compression_arm_thumb->deinit(NULL); finish_without_clean: bootutil_sha_drop(&sha_ctx); @@ -353,7 +408,6 @@ static int boot_copy_protected_tlvs(const struct image_header *hdr, BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); rc = BOOT_EFLASH; - goto out; } @@ -422,7 +476,6 @@ static int boot_copy_protected_tlvs(const struct image_header *hdr, BOOT_LOG_ERR( "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); - goto out; } @@ -438,7 +491,6 @@ static int boot_copy_protected_tlvs(const struct image_header *hdr, "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); rc = BOOT_EFLASH; - goto out; } @@ -513,7 +565,6 @@ static int boot_sha_protected_tlvs(const struct image_header *hdr, BOOT_LOG_ERR( "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", (off + read_off), copy_size, fap_src->fa_id, rc); - goto out; } @@ -616,7 +667,6 @@ int boot_size_unprotected_tlvs(const struct image_header *hdr, const struct flas */ BOOT_LOG_ERR("No unprotected TLVs in post-decompressed image output, image is invalid"); rc = BOOT_EBADIMAGE; - goto out; } @@ -671,7 +721,6 @@ static int boot_copy_unprotected_tlvs(const struct image_header *hdr, BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); rc = BOOT_EFLASH; - goto out; } @@ -768,7 +817,6 @@ static int boot_copy_unprotected_tlvs(const struct image_header *hdr, BOOT_LOG_ERR( "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); - goto out; } @@ -784,7 +832,6 @@ static int boot_copy_unprotected_tlvs(const struct image_header *hdr, "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); rc = BOOT_EFLASH; - goto out; } @@ -813,7 +860,8 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl uint32_t unprotected_tlv_size = 0; uint32_t tlv_write_size = 0; uint32_t decompressed_image_size; - struct nrf_compress_implementation *compression = NULL; + struct nrf_compress_implementation *compression_lzma = NULL; + struct nrf_compress_implementation *compression_arm_thumb = NULL; struct image_header *hdr; TARGET_STATIC uint8_t decomp_buf[CONFIG_BOOT_DECOMPRESSION_BUFFER_SIZE] __attribute__((aligned(4))); TARGET_STATIC struct image_header modified_hdr; @@ -831,27 +879,26 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl */ BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); rc = BOOT_EBADIMAGE; - goto finish; } - compression = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + compression_lzma = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + compression_arm_thumb = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_ARM_THUMB); - if (compression == NULL || compression->init == NULL || compression->deinit == NULL || - compression->decompress_bytes_needed == NULL || compression->decompress == NULL) { + if (!is_compression_object_valid(compression_lzma) || + !is_compression_object_valid(compression_arm_thumb)) { /* Compression library missing or missing required function pointer */ BOOT_LOG_ERR("Decompression library fatal error"); rc = BOOT_EBADSTATUS; - goto finish; } - rc = compression->init(NULL); + rc = compression_lzma->init(NULL); + rc = compression_arm_thumb->init(NULL); if (rc) { BOOT_LOG_ERR("Decompression library fatal error"); rc = BOOT_EBADSTATUS; - goto finish; } @@ -864,7 +911,6 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl if (rc) { BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); rc = BOOT_EBADIMAGE; - goto finish; } @@ -877,7 +923,6 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl if (rc) { BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); rc = BOOT_EBADIMAGE; - goto finish; } @@ -888,7 +933,6 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl if (rc) { BOOT_LOG_ERR("Unable to determine unprotected TLV size of compressed image"); rc = BOOT_EBADIMAGE; - goto finish; } @@ -899,7 +943,6 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", off_dst, sizeof(modified_hdr), fap_dst->fa_id, rc); rc = BOOT_EFLASH; - goto finish; } @@ -918,7 +961,6 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", (off_src + hdr->ih_hdr_size + pos), copy_size, fap_src->fa_id, rc); rc = BOOT_EFLASH; - goto finish; } @@ -933,7 +975,7 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl uint8_t *output = NULL; bool last_packet = false; - chunk_size = compression->decompress_bytes_needed(NULL); + chunk_size = compression_lzma->decompress_bytes_needed(NULL); if (chunk_size > (copy_size - tmp_off)) { chunk_size = (copy_size - tmp_off); @@ -943,13 +985,12 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl last_packet = true; } - rc = compression->decompress(NULL, &buf[tmp_off], chunk_size, last_packet, &offset, + rc = compression_lzma->decompress(NULL, &buf[tmp_off], chunk_size, last_packet, &offset, &output, &output_size); if (rc) { BOOT_LOG_ERR("Decompression error: %d", rc); rc = BOOT_EBADSTATUS; - goto finish; } @@ -969,6 +1010,45 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl /* Write data out from secondary buffer when it is full */ if (decomp_buf_size == sizeof(decomp_buf)) { + if (hdr->ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT) { + /* Run this through the ARM thumb filter */ + uint32_t offset_arm_thumb = 0; + uint32_t output_size_arm_thumb = 0; + uint32_t processed_size = 0; + uint8_t *output_arm_thumb = NULL; + + while (processed_size < sizeof(decomp_buf)) { + uint32_t current_size = sizeof(decomp_buf); + bool arm_thumb_last_packet = false; + + if (current_size > CONFIG_NRF_COMPRESS_CHUNK_SIZE) { + current_size = CONFIG_NRF_COMPRESS_CHUNK_SIZE; + } + + if (last_packet && (processed_size + current_size) == + sizeof(decomp_buf)) { + arm_thumb_last_packet = true; + } + + rc = compression_arm_thumb->decompress(NULL, + &decomp_buf[processed_size], + current_size, + arm_thumb_last_packet, + &offset_arm_thumb, + &output_arm_thumb, + &output_size_arm_thumb); + + if (rc) { + BOOT_LOG_ERR("Decompression error: %d", rc); + rc = BOOT_EBADSTATUS; + goto finish; + } + + memcpy(&decomp_buf[processed_size], output_arm_thumb, current_size); + processed_size += current_size; + } + } + rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), decomp_buf, sizeof(decomp_buf)); @@ -978,7 +1058,6 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl (off_dst + hdr->ih_hdr_size + write_pos), sizeof(decomp_buf), fap_dst->fa_id, rc); rc = BOOT_EFLASH; - goto finish; } @@ -994,7 +1073,8 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl } /* Clean up decompression system */ - (void)compression->deinit(NULL); + (void)compression_lzma->deinit(NULL); + (void)compression_arm_thumb->deinit(NULL); if (protected_tlv_size > 0) { rc = boot_copy_protected_tlvs(hdr, fap_src, fap_dst, (off_dst + hdr->ih_hdr_size + @@ -1004,7 +1084,6 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl if (rc) { BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); - goto finish; } @@ -1019,7 +1098,6 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl if (rc) { BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); - goto finish; } @@ -1046,7 +1124,6 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl (off_dst + hdr->ih_hdr_size + write_pos), sizeof(decomp_buf_size), fap_dst->fa_id, rc); rc = BOOT_EFLASH; - goto finish; } @@ -1088,7 +1165,6 @@ int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct fl if (len != sizeof(*img_decomp_size)) { BOOT_LOG_ERR("Invalid decompressed image size TLV: %d", len); - return BOOT_EBADIMAGE; } @@ -1097,7 +1173,6 @@ int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct fl if (rc) { BOOT_LOG_ERR("Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", off, len, fap->fa_id, rc); - return BOOT_EFLASH; } From 94212b4e3853b7b09acf0e2e1ec2b895bbbb2948 Mon Sep 17 00:00:00 2001 From: Mateusz Michalek Date: Fri, 4 Oct 2024 13:36:52 +0200 Subject: [PATCH 235/238] [nrf fromlist] scripts: imgtool: compression ARM thumb filter Adds ARM thumb filter to imgtool's LZMA2 compression. Upstream PR: https://github.com/mcu-tools/mcuboot/pull/2084 Signed-off-by: Mateusz Michalek --- scripts/imgtool/image.py | 5 ++++- scripts/imgtool/main.py | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py index 10de2a33f..84811806d 100644 --- a/scripts/imgtool/image.py +++ b/scripts/imgtool/image.py @@ -70,6 +70,7 @@ 'ROM_FIXED': 0x0000100, 'COMPRESSED_LZMA1': 0x0000200, 'COMPRESSED_LZMA2': 0x0000400, + 'COMPRESSED_ARM_THUMB': 0x0000800, } TLV_VALUES = { @@ -532,8 +533,10 @@ def create(self, key, public_key_format, enckey, dependencies=None, compression_flags = 0x0 if compression_tlvs is not None: - if compression_type == "lzma2": + if compression_type in ["lzma2", "lzma2armthumb"]: compression_flags = IMAGE_F['COMPRESSED_LZMA2'] + if compression_type == "lzma2armthumb": + compression_flags |= IMAGE_F['COMPRESSED_ARM_THUMB'] # This adds the header to the payload as well if encrypt_keylen == 256: self.add_header(enckey, protected_tlv_size, compression_flags, 256) diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index 03bb565c5..94952a838 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -363,7 +363,7 @@ def convert(self, value, param, ctx): help='When encrypting the image using AES, select a 128 bit or ' '256 bit key len.') @click.option('--compression', default='disabled', - type=click.Choice(['disabled', 'lzma2']), + type=click.Choice(['disabled', 'lzma2', 'lzma2armthumb']), help='Enable image compression using specified type. ' 'Will fall back without image compression automatically ' 'if the compression increases the image size.') @@ -513,7 +513,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, custom_tlvs, compression_tlvs, int(encrypt_keylen), clear, baked_signature, pub_key, vector_to_sign, user_sha) - if compression == "lzma2": + if compression in ["lzma2", "lzma2armthumb"]: compressed_img = image.Image(version=decode_version(version), header_size=header_size, pad_header=pad_header, pad=pad, confirm=confirm, align=int(align), @@ -527,6 +527,8 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, "dict_size": comp_default_dictsize, "lp": comp_default_lp, "lc": comp_default_lc} ] + if compression == "lzma2armthumb": + compression_filters.insert(0, {"id":lzma.FILTER_ARMTHUMB}) compressed_data = lzma.compress(img.get_infile_data(),filters=compression_filters, format=lzma.FORMAT_RAW) uncompressed_size = len(img.get_infile_data()) From 54b63077e38af82420ecd94c857a07678a7ad718 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 8 Oct 2024 16:31:48 +0000 Subject: [PATCH 236/238] [nrf fromlist] bootutil: Allow bypassing ASN.1 encoding for ED25519 key import The commit adds MCUBOOT_KEY_IMPORT_BYPASS_ASN configuration option that allows bypassing ASN.1 decoding of ED25519 public key, compiled into MCUboot. When the option is enabled the key will be accessed directly and ASN.1 processing is not compiled in, resulting in smaller footprint of MCUboot, at a cost of reduced detection of invalid key, i.e. public key designated for different method than compiled in. Upstream PR: https://github.com/mcu-tools/mcuboot/pull/2089 Signed-off-by: Dominik Ermel --- boot/bootutil/src/image_ed25519.c | 19 ++++++++++++++++++- .../include/mcuboot_config/mcuboot_config.h | 4 ++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 40d494bcf..93fd5de88 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -26,16 +26,18 @@ #define EDDSA_SIGNATURE_LENGTH 64 -static const uint8_t ed25519_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x65\x70"; #define NUM_ED25519_BYTES 32 extern int ED25519_verify(const uint8_t *message, size_t message_len, const uint8_t signature[EDDSA_SIGNATURE_LENGTH], const uint8_t public_key[NUM_ED25519_BYTES]); +#if !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN) /* * Parse the public key used for signing. */ +static const uint8_t ed25519_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x65\x70"; + static int bootutil_import_key(uint8_t **cp, uint8_t *end) { @@ -71,6 +73,7 @@ bootutil_import_key(uint8_t **cp, uint8_t *end) return 0; } +#endif /* !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN) */ fih_ret bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, @@ -89,11 +92,25 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, pubkey = (uint8_t *)bootutil_keys[key_id].key; end = pubkey + *bootutil_keys[key_id].len; +#if !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN) rc = bootutil_import_key(&pubkey, end); if (rc) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } +#else + /* Directly use the key contents from the ASN stream, + * these are the last NUM_ED25519_BYTES. + * There is no check whether this is the correct key, + * here, by the algorithm selected. + */ + if (*bootutil_keys[key_id].len < NUM_ED25519_BYTES) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + + pubkey = end - NUM_ED25519_BYTES; +#endif rc = ED25519_verify(hash, IMAGE_HASH_SIZE, sig, pubkey); diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 7896e0939..bc5188138 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -34,6 +34,10 @@ # error "One crypto library implementation allowed at a time." #endif +#if defined(CONFIG_BOOT_KEY_IMPORT_BYPASS_ASN) +#define MCUBOOT_KEY_IMPORT_BYPASS_ASN +#endif + #ifdef CONFIG_BOOT_USE_MBEDTLS #define MCUBOOT_USE_MBED_TLS #elif defined(CONFIG_BOOT_USE_TINYCRYPT) From 36fc9d3cd4a91cd5619d220294a21569efd90f47 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 8 Oct 2024 16:36:15 +0000 Subject: [PATCH 237/238] [nrf fromlist] zephyr: Add Kconfig option CONFIG_BOOT_KEY_IMPORT_BYPASS_ASN The option enables MCUboot configuration option MCUBOOT_KEY_IMPORT_BYPASS_ASN. Upstream PR: https://github.com/mcu-tools/mcuboot/pull/2089 Signed-off-by: Dominik Ermel --- boot/zephyr/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 9022a0ce5..c82ed629c 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -299,6 +299,15 @@ config BOOT_ED25519_PSA select BOOT_X25519_PSA_DEPENDENCIES if BOOT_ENCRYPT_IMAGE endchoice + +config BOOT_KEY_IMPORT_BYPASS_ASN + bool "Directly access key value without ASN.1 parsing" + help + Originally, public keys compiled into MCUboot were + stored in ASN.1 encoded format. Enabling this option + bypasses the ASN.1 decoding and directly accesses the key + in ASN.1 bitstream; this reduces MCUboot code by removing + the ASN.1 processing. endif endchoice From 8c99a50b98d440f107080f4aaa9b3d1fe11300a9 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 9 Oct 2024 12:34:28 +0000 Subject: [PATCH 238/238] [nrf noup] Add ASN.1 bypass to bootutil_verify_img Allow ASN.1 bypass for image verification. Signed-off-by: Dominik Ermel --- boot/bootutil/src/image_ed25519.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 93fd5de88..f4914ac00 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -143,11 +143,25 @@ bootutil_verify_img(const uint8_t *img, uint32_t size, pubkey = (uint8_t *)bootutil_keys[key_id].key; end = pubkey + *bootutil_keys[key_id].len; +#if !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN) rc = bootutil_import_key(&pubkey, end); if (rc) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } +#else + /* Directly use the key contents from the ASN stream, + * these are the last NUM_ED25519_BYTES. + * There is no check whether this is the correct key, + * here, by the algorithm selected. + */ + if (*bootutil_keys[key_id].len < NUM_ED25519_BYTES) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + + pubkey = end - NUM_ED25519_BYTES; +#endif rc = ED25519_verify(img, size, sig, pubkey);