Infineon: Add secure mode smif encryption feature for CYW20829 devices
diff --git a/.gitmodules b/.gitmodules
index bfb47cf..c8aa372 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,19 +1,20 @@
-
-[submodule "boot/cypress/libs/cmsis"]
- path = boot/cypress/libs/cmsis
- url = https://github.com/Infineon/cmsis.git
[submodule "boot/cypress/libs/core-lib"]
path = boot/cypress/libs/core-lib
url = https://github.com/Infineon/core-lib.git
-[submodule "boot/cypress/libs/mtb-pdl-cat1"]
- path = boot/cypress/libs/mtb-pdl-cat1
- url = https://github.com/Infineon/mtb-pdl-cat1.git
-[submodule "boot/cypress/libs/mtb-hal-cat1"]
- path = boot/cypress/libs/mtb-hal-cat1
- url = https://github.com/Infineon/mtb-hal-cat1.git
[submodule "boot/cypress/libs/cy-mbedtls-acceleration"]
path = boot/cypress/libs/cy-mbedtls-acceleration
url = https://github.com/Infineon/cy-mbedtls-acceleration.git
+ branch = c5f703d0354c69611e6c8226a609cead96e1f8a6
+[submodule "boot/cypress/libs/mtb-hal-cat1"]
+ path = boot/cypress/libs/mtb-hal-cat1
+ url = https://github.com/Infineon/mtb-hal-cat1.git
+[submodule "boot/cypress/libs/mtb-pdl-cat1"]
+ path = boot/cypress/libs/mtb-pdl-cat1
+ url = https://github.com/Infineon/mtb-pdl-cat1.git
+ branch = 4eb815bb8c6f455b0c516ec86b2e16b02bd367d7
+[submodule "boot/cypress/libs/cmsis"]
+ path = boot/cypress/libs/cmsis
+ url = https://github.com/Infineon/cmsis.git
[submodule "ext/cddl-gen"]
path = ext/cddl-gen
url = https://github.com/NordicSemiconductor/cddl-gen.git
diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c
index f9059aa..8df258a 100644
--- a/boot/bootutil/src/bootutil_misc.c
+++ b/boot/bootutil/src/bootutil_misc.c
@@ -202,7 +202,7 @@
return BOOT_MAGIC_BAD;
}
-static inline uint32_t
+uint32_t
boot_magic_off(const struct flash_area *fap)
{
return flash_area_get_size(fap) - BOOT_MAGIC_SZ;
diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h
index 105237a..045cacf 100644
--- a/boot/bootutil/src/bootutil_priv.h
+++ b/boot/bootutil/src/bootutil_priv.h
@@ -276,7 +276,9 @@
uint32_t boot_trailer_sz(uint32_t min_write_sz);
int boot_status_entries(int image_index, const struct flash_area *fap);
uint32_t boot_status_off(const struct flash_area *fap);
+uint32_t boot_magic_off(const struct flash_area *fap);
int boot_write_magic(const struct flash_area *fap);
+int boot_clear_magic(const struct flash_area *fap);
int boot_write_status(const struct boot_loader_state *state, struct boot_status *bs);
int boot_write_copy_done(const struct flash_area *fap);
int boot_write_image_ok(const struct flash_area *fap);
diff --git a/boot/bootutil/src/bootutil_public.c b/boot/bootutil/src/bootutil_public.c
index 82763d2..38b2bd1 100644
--- a/boot/bootutil/src/bootutil_public.c
+++ b/boot/bootutil/src/bootutil_public.c
@@ -126,7 +126,7 @@
.image_ok_secondary_slot = BOOT_FLAG_ANY,
.copy_done_primary_slot = BOOT_FLAG_SET,
.swap_type = BOOT_SWAP_TYPE_REVERT,
- },
+ }
};
#define BOOT_SWAP_TABLES_COUNT \
@@ -153,11 +153,6 @@
}
#ifndef MCUBOOT_SWAP_USING_STATUS
-static inline uint32_t
-boot_magic_off(const struct flash_area *fap)
-{
- return flash_area_get_size(fap) - BOOT_MAGIC_SZ;
-}
static inline uint32_t
boot_image_ok_off(const struct flash_area *fap)
@@ -326,6 +321,42 @@
#ifndef MCUBOOT_SWAP_USING_STATUS
int
+boot_clear_magic(const struct flash_area *fap)
+{
+ uint32_t off;
+ uint32_t pad_off;
+ int rc;
+ uint8_t magic[BOOT_MAGIC_ALIGN_SIZE];
+ uint8_t erased_val;
+
+ off = boot_magic_off(fap);
+
+ /* image_trailer structure was modified with additional padding such that
+ * the pad+magic ends up in a flash minimum write region. The address
+ * returned by boot_magic_off() is the start of magic which is not the
+ * start of the flash write boundary and thus writes to the magic will fail.
+ * To account for this change, write to magic is first padded with 0xFF
+ * before writing to the trailer.
+ */
+ pad_off = ALIGN_DOWN(off, BOOT_MAX_ALIGN);
+
+ erased_val = flash_area_erased_val(fap);
+
+ (void)memset(&magic[0], erased_val, sizeof(magic));
+
+ BOOT_LOG_DBG("clearing magic; fa_id=%u off=0x%" PRIx32
+ " (0x%" PRIx32 ")", (unsigned)flash_area_get_id(fap),
+ off, flash_area_get_off(fap) + off);
+ rc = flash_area_write(fap, pad_off, &magic[0], BOOT_MAGIC_ALIGN_SIZE);
+
+ if (rc != 0) {
+ return BOOT_EFLASH;
+ }
+
+ return 0;
+}
+
+int
boot_write_magic(const struct flash_area *fap)
{
uint32_t off;
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index ddca260..8ede0f1 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -1753,6 +1753,9 @@
if (BOOT_IS_UPGRADE(swap_type)) {
rc = swap_set_copy_done(BOOT_CURR_IMG(state));
+#if defined(MCUBOOT_ENC_IMAGES_SMIF)
+ rc |= swap_clear_magic_upgrade(BOOT_CURR_IMG(state));
+#endif
if (rc != 0) {
BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_PANIC;
}
diff --git a/boot/bootutil/src/swap_misc.c b/boot/bootutil/src/swap_misc.c
index 64485db..f5a631f 100644
--- a/boot/bootutil/src/swap_misc.c
+++ b/boot/bootutil/src/swap_misc.c
@@ -87,7 +87,7 @@
const struct flash_area *fap,
const struct boot_status *bs)
{
- struct boot_swap_state swap_state;
+ struct boot_swap_state swap_state = {0};
uint8_t image_index;
int rc;
@@ -127,7 +127,7 @@
rc = boot_write_magic(fap);
assert(rc == 0);
- return 0;
+ return rc;
}
int
@@ -205,6 +205,21 @@
return rc;
}
+int swap_clear_magic_upgrade(uint8_t image_index)
+{
+ const struct flash_area *fap = NULL;
+ int rc;
+
+ rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_index), &fap);
+ if (rc != 0) {
+ return BOOT_EFLASH;
+ }
+
+ rc = boot_clear_magic(fap);
+ flash_area_close(fap);
+ return rc;
+}
+
int
swap_set_image_ok(uint8_t image_index)
{
diff --git a/boot/bootutil/src/swap_priv.h b/boot/bootutil/src/swap_priv.h
index 86d0b72..9baec58 100644
--- a/boot/bootutil/src/swap_priv.h
+++ b/boot/bootutil/src/swap_priv.h
@@ -72,6 +72,11 @@
int swap_set_copy_done(uint8_t image_index);
/**
+ * Marks the image in the secondary slot as upgraded.
+ */
+int swap_clear_magic_upgrade(uint8_t image_index);
+
+/**
* Marks a reverted image in the primary slot as confirmed. This is necessary to
* ensure the status bytes from the image revert operation don't get processed
* on a subsequent boot.
diff --git a/boot/bootutil/src/swap_status_misc.c b/boot/bootutil/src/swap_status_misc.c
index b5fc1ed..bc44feb 100644
--- a/boot/bootutil/src/swap_status_misc.c
+++ b/boot/bootutil/src/swap_status_misc.c
@@ -69,7 +69,7 @@
}
/* Offset Section */
-static inline uint32_t
+uint32_t
boot_magic_off(const struct flash_area *fap)
{
(void)fap;
@@ -246,6 +246,25 @@
return 0;
}
+int
+boot_clear_magic(const struct flash_area *fap)
+{
+ uint32_t off;
+ int rc;
+ uint8_t tmp[BOOT_MAGIC_SZ];
+
+ off = fap->fa_size - BOOT_MAGIC_SZ;
+
+ (void) memset(tmp, flash_area_erased_val(fap), BOOT_MAGIC_SZ);
+
+ rc = flash_area_write(fap, off, tmp, BOOT_MAGIC_ALIGN_SIZE);
+
+ if (rc != 0) {
+ return -1;
+ }
+ return 0;
+}
+
/**
* Writes the supplied boot status to the flash file system. The boot status
* contains the current state of an in-progress image copy operation.
diff --git a/boot/cypress/BlinkyApp/BlinkyApp.md b/boot/cypress/BlinkyApp/BlinkyApp.md
index e85f239..7c7100b 100644
--- a/boot/cypress/BlinkyApp/BlinkyApp.md
+++ b/boot/cypress/BlinkyApp/BlinkyApp.md
@@ -4,17 +4,7 @@
Implements a simple Blinky LED application to demonstrate the MCUBootApp bootloader application operation for the boot and upgrade processes.
-This demo supports PSoC™ 6 chips with the 1M-, 2M-, and 512K-flash on board; XMC7200, XMC7100; CYW20829/CYW89829 chips with no internal flash.
-The evaluation kits are:
-* `CY8CPROTO-062-4343W`
-* `CY8CKIT-062-WIFI-BT`
-* `CY8CPROTO-062S3-4343W`
-* `CYW920829M2EVB-01`
-* `CYW989829M2EVB-01`
-* `CYBLE-416045-EVAL`
-* `CY8CPROTO-063-BLE`
-* `CY8CKIT-062-BLE`
-* `KIT_XMC72_EVK`
+It is validated and started by MCUBootApp, which is running on the CM0p core of PSoC™ 6 devices, or CM33 core for the CYW20829/CYW89829 devices.
Functionality:
@@ -97,7 +87,7 @@
`MCUBootApp` can upgrade an image either by overwriting the image from a secondary slot to a primary slot or by swapping the two images.
To build `BlinkyApp` for different upgrade modes choose flash map JSON file with the corresponding suffix - either `_swap_` or `_overwrite_`.
But hold in the mind, that `MCUBootApp` and `BlinkyApp` should use the same flash map file!
-For example: to building `MCUBootApp` and `BlinkyApp` in the 'single overwride' mode use the flash map file:
+For example: to building `MCUBootApp` and `BlinkyApp` in the 'single overwrite' mode use the flash map file:
`FLASH_MAP=platforms/memory/PSOC6/flashmap/psoc6_overwrite_single.json`
**Single-image**
@@ -265,7 +255,7 @@
$OPENOCD_PATH/bin/openocd -s "$OPENOCD_PATH/scripts" -f "$OPENOCD_PATH/ scripts/interface/kitprog3.cfg" -f "$OPENOCD_PATH/scripts/target/psoc6_2m.cfg" -c "init; reset init" -c "flash erase_address 0x10078000 0x2000" -c "reset; shutdown"
-In both cases, it is easier to erase the whole device flash or all flash after MCUBootApp. This command erases all flash after MCUBootApp, including the primary, secondary, and swap status partiton:
+In both cases, it is easier to erase the whole device flash or all flash after MCUBootApp. This command erases all flash after MCUBootApp, including the primary, secondary, and swap status partition:
$OPENOCD_PATH/bin/openocd -s "$OPENOCD_PATH/scripts" -f "$OPENOCD_PATH/ scripts/interface/kitprog3.cfg" -f "$OPENOCD_PATH/scripts/target/psoc6_2m.cfg" -c "init; reset init" -c "flash erase_address 0x10018000 0x1E8000" -c "reset; shutdown"
diff --git a/boot/cypress/MCUBootApp/ExternalMemory.md b/boot/cypress/MCUBootApp/ExternalMemory.md
index c2a6ca4..07598cb 100644
--- a/boot/cypress/MCUBootApp/ExternalMemory.md
+++ b/boot/cypress/MCUBootApp/ExternalMemory.md
@@ -80,7 +80,7 @@
External memory is enabled when `make` flag `USE_EXTERNAL_FLASH` is set to `1`. Value of this flag is set in auto-generated `memorymap.mk` files when field `"external_flash"` is present in JSON file.
-Default flash maps with suffix _smif_ are provided in `platforms/memory/PSOC6/flashmap` folder for PSoC™ 6 devices, where presense of external memory in system is optional.
+Default flash maps with suffix _smif_ are provided in `platforms/memory/PSOC6/flashmap` folder for PSoC™ 6 devices, where presence of external memory in system is optional.
Build MCUBootApp as described in the [MCUBootApp.md](MCUBootApp.md) file.
diff --git a/boot/cypress/MCUBootApp/MCUBootApp.md b/boot/cypress/MCUBootApp/MCUBootApp.md
index b5bc044..2bdcbaf 100644
--- a/boot/cypress/MCUBootApp/MCUBootApp.md
+++ b/boot/cypress/MCUBootApp/MCUBootApp.md
@@ -11,7 +11,7 @@
* Revert bad upgrade images
* Secondary slots located in external flash
-This demo supports PSoC™ 6 chips with the 1M-, 2M-, and 512K-flash on board; XMC7200, XMC7100; CYW20829/CYW89829 chips with no internal flash.
+This demo supports PSoC™ 6 chips with the 1M-, 2M-, and 512K-flash on board, and the CYW20829/CYW89829 chips with no internal flash.
The evaluation kits are:
* `CY8CPROTO-062-4343W`
* `CY8CKIT-062-WIFI-BT`
@@ -23,7 +23,7 @@
* `CY8CKIT-062-BLE`
* `KIT_XMC72_EVK`
-### Platfrom specifics
+### Platform specifics
MCUBootApp can be built for different platforms. So, the main application makefile `MCUBootApp.mk` operates with common build variables and flags. Most of them can be passed to the build system as a `make` command parameter and each platform defines the default value prefixed with `PLATFORM_` in the corresponding makefile - `PSOC6.mk` or `CYW20829.mk`. The build flags and variables are described in detail in the following paragraphs.
@@ -153,6 +153,8 @@
```
To calculate the minimal correct size of the status partition, one could specify `"value": "0"` for the `"status_size"`. After the intentional `make` failure, copy the correct size from the error message.
+To improve boot time user may specify build variables `MCUBOOT_SWAP_STATUS_FAST_BOOT=1` `USE_BOOTSTRAP=0` and comment out `MCUBOOT_VALIDATE_PRIMARY_SLOT` in "mcuboot_config.h" to achieve faster boot.
+
###### External flash
If external flash memory is used, one should specify its parameters. The first way is to specify the exact model:
@@ -583,9 +585,6 @@
Misaligned application_1 (secondary slot) - suggested address 0x18030200
```
This gives the nearest larger address that satisfies the slot location requirements. Other errors, such as overlapping flash areas, are also checked and reported.
-
-To improve boot time user may specify build variables `MCUBOOT_SWAP_STATUS_FAST_BOOT=1` `USE_BOOTSTRAP=0` and comment out `MCUBOOT_VALIDATE_PRIMARY_SLOT` in "mcuboot_config.h" to achieve faser boot.
-
### Hardware limitations
This application is created to demonstrate the MCUboot library features and not as a reference example. So, some considerations are taken.
diff --git a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h
index a1e36ba..eed3573 100644
--- a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h
+++ b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h
@@ -57,8 +57,10 @@
* Uncomment which is needed. */
#define MCUBOOT_SWAP_USING_SCRATCH 1
/* #define MCUBOOT_SWAP_USING_MOVE 1 */
+#ifdef USE_SWAP_STATUS
#define MCUBOOT_SWAP_USING_STATUS 1
#endif
+#endif
/* This definition is used in boot_copy_region function to define
* minimum size of data chunk to be copied. This most likely is equal
diff --git a/boot/cypress/MCUBootApp/main.c b/boot/cypress/MCUBootApp/main.c
index b526d77..06dd387 100644
--- a/boot/cypress/MCUBootApp/main.c
+++ b/boot/cypress/MCUBootApp/main.c
@@ -377,9 +377,11 @@
* reset will be initiated by watchdog timer and swap revert operation started
* to roll back to operable image.
*/
- cyhal_wdt_t *wdt = NULL;
+ cyhal_wdt_t wdt_obj;
- rc = cyhal_wdt_init(wdt, WDT_TIME_OUT_MS);
+ rc = cyhal_wdt_init(&wdt_obj, WDT_TIME_OUT_MS);
+
+ cyhal_wdt_start(&wdt_obj);
if (CY_RSLT_SUCCESS == rc) {
diff --git a/boot/cypress/README.md b/boot/cypress/README.md
index 60a5a50..a659281 100644
--- a/boot/cypress/README.md
+++ b/boot/cypress/README.md
@@ -2,32 +2,44 @@
### Disclaimer
-Given solution is included in `MCUboot` repository with purpose to demonstrate basic consepts and features of MCUboot library on Infineon Technologies devices.
+Given solution is included in `MCUboot` repository with purpose to demonstrate basic concepts and features of MCUboot library on Cypress PSoC 6 device. Applications are created per MCUboot library maintainers requirements. Implementation differs from conventional and recommended by Cypress Semiconductors development flow for PSoC 6 devices. These applications are not recommended as a starting point for development and should not be considered as supported examples for PSoC 6 devices.
-### Supported platforms
+Examples provided to use with **ModusToolbox® Software Environment** are a recommended reference point to start development of MCUboot based bootloaders for PSoC 6 devices.
-| Family | Platforms |
----------- | -------------------|
-| PSOC6 | PSOC6 1M, 2M, 512K |
-| CYWxx829 | CYW20829, CYW89829 |
-| XMC7x00 | XMC7200, XMC7100 |
+Refer to **Cypress Semiconductors** [github](https://github.com/cypresssemiconductorco) page to find examples.
+
+1. MCUboot-Based Basic Bootloader [mtb-example-psoc6-mcuboot-basic](https://github.com/cypresssemiconductorco/mtb-example-psoc6-mcuboot-basic)
+2. MCUboot-Based Bootloader with Rollback to Factory App in External Flash [mtb-example-anycloud-mcuboot-rollback](https://github.com/cypresssemiconductorco/mtb-example-anycloud-mcuboot-rollback)
### Solution description
There are two applications implemented:
-* MCUBootApp - MCUboot-based bootloader implementation;
-* BlinkyApp - simple blinking LED application which is a target of BOOT/UPGRADE;
+* MCUBootApp - PSoC6 MCUboot-based bootloading application;
+* BlinkyApp - simple PSoC6 blinking LED application which is a target of BOOT/UPGRADE;
-Detailed description on each application is provided in dedicated files:
+The default flash map for MCUBootApp implemented is next:
-Bootloader - [MCUBootApp.md](./MCUBootApp/MCUBootApp.md)
-Test Application - [BlinkyApp.md](./BlinkyApp/BlinkyApp.md)
+* [0x10000000, 0x10018000] - MCUBootApp (bootloader) area;
+* [0x10018000, 0x10028000] - primary slot for BlinkyApp;
+* [0x10028000, 0x10038000] - secondary slot for BlinkyApp;
+* [0x10038000, 0x10039000] - scratch area;
-Separate documentation is available for External Memory usage in mcuboot [ExternalMemory.md](./MCUBootApp/ExternalMemory.md)
+The flash map is defined through sysflash.h and memory.c.
-### Downloading solution
+It is also possible to place secondary (upgrade) slots in external memory module. In this case primary slot can be doubled in size.
+For more details about External Memory usage, please refer to separate guiding document `MCUBootApp/ExternalMemory.md`.
-Since libraries required by mcuboot Infineon implementation are implemented as submodules following commands needs to be executed.
+MCUBootApp checks image integrity with SHA256, image authenticity with EC256 digital signature verification and uses either completely software implementation of cryptographic functions or accelerated by hardware - both based on Mbed TLS Library.
+
+### Downloading solution's assets
+
+There is a set assets required:
+
+* MCUBooot Library (root repository)
+* PSoC6 Peripheral Drivers Library (PDL)
+* Mbed TLS Cryptographic Library
+
+Those are represented as submodules.
To retrieve source code with subsequent submodules pull:
@@ -44,22 +56,24 @@
Root directory for build is **boot/cypress.**
-This folder contains make files infrastructure for building both MCUbootApp and sample BlinkyApp application used for Bootloader demo functionality.
+This folder contains make files infrastructure for building both MCUboot Bootloader and sample BlinkyApp application used for Bootloader demo functionality.
-**GCC_ARM** is only supported toolchain.
+Instructions on how to build and upload MCUBootApp bootloader application and sample user application are located in `Readme.md` files in corresponding folders.
-It is recommended to use [ModusToolbox™ Software Environment](https://www.cypress.com/products/modustoolbox) which includes GCC Toolchain.
+Supported platforms for `MCUboot`, `BlinkyApp`:
+
+**GCC_ARM** is only supported (built and verified on GCC 9.3.1).
+
+It is included with [ModusToolbox™ Software Environment](https://www.cypress.com/products/modustoolbox).
The default installation folder is expected by the makefile build system.
To use another installation folder, version of **ModusToolbox™ IDE** or another GCC Compiler, specify the path to a toolchain using the **TOOLCHAIN_PATH** parameter.
-Below is an example on how to set toolchain path to the latest include with **ModusToolbox™ IDE**:
+Below is an example on how to set toolchain path to the latest include with **ModusToolbox™ IDE 3.2**:
make clean app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M BUILDCFG=Debug FLASH_MAP=platforms/memory/PSOC6/flashmap/psoc6_swap_single.json TOOLCHAIN_PATH=c:/Users/${USERNAME}/ModusToolbox/tools_3.2/gcc
-**Python3** needs to be installed in system since build process required execution of prebuild and postbuild scripts in python.
-
### Build environment troubleshooting
Following CLI / IDE are supported for project build:
diff --git a/boot/cypress/libs/cy-mbedtls-acceleration b/boot/cypress/libs/cy-mbedtls-acceleration
index 2ca02f7..c5f703d 160000
--- a/boot/cypress/libs/cy-mbedtls-acceleration
+++ b/boot/cypress/libs/cy-mbedtls-acceleration
@@ -1 +1 @@
-Subproject commit 2ca02f7f1cd5f0b4a5e2380cc179da7b7a7b3b59
+Subproject commit c5f703d0354c69611e6c8226a609cead96e1f8a6
diff --git a/boot/cypress/platforms/BSP/CYW20829/system/COMPONENT_CM33/ns_system_cyw20829.c b/boot/cypress/platforms/BSP/CYW20829/system/COMPONENT_CM33/ns_system_cyw20829.c
index 30a600f..9adf3d7 100644
--- a/boot/cypress/platforms/BSP/CYW20829/system/COMPONENT_CM33/ns_system_cyw20829.c
+++ b/boot/cypress/platforms/BSP/CYW20829/system/COMPONENT_CM33/ns_system_cyw20829.c
@@ -128,8 +128,10 @@
(void)Cy_SystemInit(); /* typecast void to suppress a compiler warning about unused return value */
/* Unlock and disable WDT */
+#if !defined(DISABLE_WDT_FREE)
Cy_WDT_Unlock();
Cy_WDT_Disable();
+#endif
SystemCoreClockUpdate();
}
diff --git a/boot/cypress/platforms/CYW20829.md b/boot/cypress/platforms/CYW20829.md
index a870898..08a985e 100644
--- a/boot/cypress/platforms/CYW20829.md
+++ b/boot/cypress/platforms/CYW20829.md
@@ -106,6 +106,44 @@
make clean app APP_NAME=BlinkyApp PLATFORM=CYW20829 BUILDCFG=Debug FLASH_MAP=platforms/memory/CYW20829/flashmap/cyw20829_xip_swap_single.json ENC_IMG=1
+
+#### Encrypted image support using secured encryption key
+
+The CYW20829 MCU supports on-the-fly XIP (eXecute In Place) encryption utilizing a provisioned AES-128 key when the device is in a secure lifecycle state (LCS=SECURE)
+
+##### Enabling XIP Encryption
+
+To enable this feature, you need to specify an additional make parameter `SMIF_ENC=1` during the build process.
+
+##### Build Example
+
+Use the following command to build your application with XIP encryption enabled:
+
+```sh
+make app APP_NAME=MCUBootApp PLATFORM=CYW20829 BUILDCFG=Debug FLASH_MAP=platforms/memory/CYW20829/flashmap/cyw20829_xip_swap_single.json LCS=SECURE SMIF_ENC=1
+
+make clean app BUILDCFG=Debug APP_NAME=BlinkyApp PLATFORM=CYW20829 FLASH_MAP=./platforms/memory/CYW20829/flashmap/cyw20829_xip_swap_single.json IMG_TYPE=UPGRADE SMIF_ENC=1
+```
+
+##### Preparing and Encrypting Application Images
+Users must prepare non-encrypted signed images for their applications and perform manual encryption using cysecuretools with the "encrypt" command. This command requires specifying the encryption key, nonce, and image address as the initial vector (IV).
+
+##### Encryption Example
+To encrypt your application binary, use the following command:
+
+```sh
+cysecuretools -t cyw20829 encrypt --input BlinkyApp.bin --output BlinkyApp_encrypted.bin --iv 0x08020000 --enckey keys/encrypt_key.bin --nonce ./MCUBootApp/out/CYW20829/Debug/MCUBootApp.signed_nonce.bin
+```
+
+**Parameters:**
+- --input: The input application binary file (e.g., BlinkyApp.bin).
+- --output: The output encrypted application binary file (e.g., BlinkyApp_encrypted.bin).
+- --iv: The initial vector, which must be equal to the application start CBUS address. For example, if the application start address is 0x60020000, it should be converted to 0x08020000.
+- --enckey: The path to the encryption key file (e.g., keys/encrypt_key.bin).
+- --nonce: The nonce used for MCUBootApp encryption. Specify the path to the autogenerated nonce file (e.g., ./MCUBootApp/out/CYW20829/Debug/MCUBootApp.signed_nonce.bin).
+
+By following these steps, you can ensure that your application binaries are securely encrypted and ready for execution on the CYW20829 MCU with on-the-fly XIP encryption enabled.
+
### Rollback protection Support
As mentioned above, to use the rollback protection feature the device must be transferred to the SECURE lifecycle. The CYW20829/CYW89829 platform has a hardware-supported feature - a non-volatile counter (NV-counter). This feature is used by the MCUboot library to implement the rollback protection counter (security counter). NV-counter on CYW20829/CYW89829 is implemented as an Efuse-type region that can only be incremented. This means, that each time a new counter value is updated - a corresponding number of Efuse is burned.
@@ -172,7 +210,7 @@
The CYW20829/CYW89829 chip is designed so that the first stage bootloader called `BootROM` has most of the rights to modify the system - it is executed in the privileged protection context. Only BootROM can modify the content of Efuse where the NV counter is stored. BootROM supports the special type of service applications used when the user needs to modify the system. These apps are also provided with `cysecuretools` under `targets/cyw20829/packets/apps`. The `reprovisioning` application is used for NV-counter updates.
-To enable the rollback counter feaure, one have to use a JSON flash map with the `"service_app"` section. Sample flash maps are located in `boot/cypress/platforms/memory/CYW20829/flashmap/hw_rollback_prot`.
+To enable the rollback counter feature, one have to use a JSON flash map with the `"service_app"` section. Sample flash maps are located in `boot/cypress/platforms/memory/CYW20829/flashmap/hw_rollback_prot`.
The service application is supplied as a precompiled binary executed from RAM by BootROM. User should program either `cyapp_reprovisioning_signed.hex` (located at `./MCUBootApp/out/CYW20829/Debug/cyapp_reprovisioning_signed.hex`) or similar binary `./packets/apps/reprovisioning/cyapp_reprovisioning_signed.bin` (with the `"address"` specified in the `"service_app"` section of JSON flash map). Some other data is required for BootROM to execute the service app - this data is prepared by MCUBootApp.
diff --git a/boot/cypress/platforms/CYW20829.mk b/boot/cypress/platforms/CYW20829.mk
index f675610..dcea14f 100644
--- a/boot/cypress/platforms/CYW20829.mk
+++ b/boot/cypress/platforms/CYW20829.mk
@@ -39,7 +39,7 @@
ifeq ($(PLATFORM), CYW20829)
DEVICE ?= CYW20829B0LKML
else ifeq ($(PLATFORM), CYW89829)
-DEVICE ?= CYW89829B01MKSBG
+DEVICE ?= CYW89829B0KML
endif
#Led pin default config
@@ -55,6 +55,12 @@
# Add device name to defines
DEFINES += $(DEVICE)
+USE_SWAP_STATUS ?= 1
+
+ifeq ($(USE_SWAP_STATUS), 1)
+DEFINES += USE_SWAP_STATUS=1
+endif
+
# Default upgrade method
PLATFORM_DEFAULT_USE_OVERWRITE ?= 0
@@ -66,6 +72,10 @@
FLASH_START := 0x60000000
FLASH_XIP_START := 0x08000000
+ifeq ($(SMIF_ENC), 1)
+ DEFINES += MCUBOOT_ENC_IMAGES_SMIF=1
+endif
+
###############################################################################
# Application specific libraries
###############################################################################
@@ -75,6 +85,7 @@
ifeq ($(APP_NAME), MCUBootApp)
+SMIF_ENC ?= 0
DEFINES += COMPONENT_CUSTOM_DESIGN_MODUS
# Platform dependend utils files
@@ -126,6 +137,8 @@
PLATFORM_CHUNK_SIZE := 4096U
###############################################################################
+SIGN_ENC := 0
+
###############################################################################
# MCUBootApp service app definitions
###############################################################################
@@ -135,6 +148,14 @@
SERVICE_APP_PATH := $(PRJ_DIR)/packets/apps/reprovisioning$(SERVICE_APP_PLATFORM_SUFFIX)
SERVICE_APP_NAME := cyapp_reprovisioning_signed_icv0
+ifeq ($(SMIF_ENC), 1)
+ SIGN_ENC := 1
+endif
+
+ifeq ($(ENC_IMG), 1)
+ SIGN_ENC := 1
+endif
+
# Service app size is calculated here and converted to hex format
PLATFORM_SERVICE_APP_SIZE ?= 0x$(shell printf "%x" `wc -c < $(SERVICE_APP_PATH)/$(SERVICE_APP_NAME).bin`)
else
@@ -148,8 +169,8 @@
post_build: $(OUT_CFG)/$(APP_NAME).elf
ifeq ($(POST_BUILD_ENABLE), 1)
$(info [TOC2_Generate] - Execute toc2 generator script for $(APP_NAME))
- @echo $(SHELL) $(PRJ_DIR)/run_toc2_generator.sh $(LCS) $(OUT_CFG) $(APP_NAME) $(APPTYPE) $(PROVISION_PATH) $(SMIF_CRYPTO_CONFIG) $(TOOLCHAIN_PATH) $(APP_DEFAULT_POLICY) $(BOOTLOADER_SIZE) $(ENC_IMG) $(PLATFORM) $(PLATFORM_SERVICE_APP_DESC_OFFSET)
- $(shell $(PRJ_DIR)/run_toc2_generator.sh $(LCS) $(OUT_CFG) $(APP_NAME) $(APPTYPE) $(PROVISION_PATH) $(SMIF_CRYPTO_CONFIG) $(TOOLCHAIN_PATH) $(APP_DEFAULT_POLICY) $(BOOTLOADER_SIZE) $(ENC_IMG) $(PLATFORM) $(PLATFORM_SERVICE_APP_DESC_OFFSET))
+ @echo $(SHELL) $(PRJ_DIR)/run_toc2_generator.sh $(LCS) $(OUT_CFG) $(APP_NAME) $(APPTYPE) $(PROVISION_PATH) $(SMIF_CRYPTO_CONFIG) $(TOOLCHAIN_PATH) $(APP_DEFAULT_POLICY) $(BOOTLOADER_SIZE) $(SIGN_ENC) $(PLATFORM) $(PLATFORM_SERVICE_APP_DESC_OFFSET)
+ $(shell $(PRJ_DIR)/run_toc2_generator.sh $(LCS) $(OUT_CFG) $(APP_NAME) $(APPTYPE) $(PROVISION_PATH) $(SMIF_CRYPTO_CONFIG) $(TOOLCHAIN_PATH) $(APP_DEFAULT_POLICY) $(BOOTLOADER_SIZE) $(SIGN_ENC) $(PLATFORM) $(PLATFORM_SERVICE_APP_DESC_OFFSET))
# Convert binary to hex and rename
$(shell mv -f $(OUT_CFG)/$(APP_NAME).final.bin $(OUT_CFG)/$(APP_NAME).bin || rm -f $(OUT_CFG)/$(APP_NAME).bin)
diff --git a/boot/cypress/platforms/PSOC6.mk b/boot/cypress/platforms/PSOC6.mk
index 9119a7f..a12b02a 100644
--- a/boot/cypress/platforms/PSOC6.mk
+++ b/boot/cypress/platforms/PSOC6.mk
@@ -100,6 +100,7 @@
UART_RX_DEFAULT ?= P5_0
endif
+DEFINES += USE_SWAP_STATUS=1
DEFINES += CY_DEBUG_UART_TX=$(UART_TX_DEFAULT)
DEFINES += CY_DEBUG_UART_RX=$(UART_RX_DEFAULT)
DEFINES += CYBSP_DEBUG_UART_TX=$(UART_TX_DEFAULT)
diff --git a/boot/cypress/platforms/XMC7000.mk b/boot/cypress/platforms/XMC7000.mk
index de101e0..7393d6c 100644
--- a/boot/cypress/platforms/XMC7000.mk
+++ b/boot/cypress/platforms/XMC7000.mk
@@ -57,6 +57,12 @@
UART_RX_DEFAULT ?= P13_0
endif
+USE_SWAP_STATUS ?= 1
+
+ifeq ($(USE_SWAP_STATUS), 1)
+DEFINES += USE_SWAP_STATUS=1
+endif
+
# Add device name to defines
DEFINES += $(DEVICE)
diff --git a/boot/cypress/platforms/crypto/CYW20829/mbedtls/compat-2.x.h b/boot/cypress/platforms/crypto/CYW20829/mbedtls/compat-2.x.h
index e52e975..2ed6c81 100644
--- a/boot/cypress/platforms/crypto/CYW20829/mbedtls/compat-2.x.h
+++ b/boot/cypress/platforms/crypto/CYW20829/mbedtls/compat-2.x.h
@@ -32,7 +32,6 @@
size_t ilen );
static inline int mbedtls_sha256_update_ret(void *ctx,
-
const unsigned char *input,
size_t ilen)
{
@@ -44,7 +43,7 @@
return -MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
}
else {
-#ifdef MCUBOOT_ENC_IMAGES_XIP
+#if defined(MCUBOOT_ENC_IMAGES_XIP) || defined(MCUBOOT_ENC_IMAGES_SMIF)
/* Process chunks copied to SRAM */
uint8_t tmp_buf[0x400];
size_t offs = 0;
diff --git a/boot/cypress/platforms/img_confirm/CYW20829/set_img_ok.c b/boot/cypress/platforms/img_confirm/CYW20829/set_img_ok.c
index 275dfd6..45dd60a 100644
--- a/boot/cypress/platforms/img_confirm/CYW20829/set_img_ok.c
+++ b/boot/cypress/platforms/img_confirm/CYW20829/set_img_ok.c
@@ -1,122 +1,100 @@
/********************************************************************************
-* Copyright 2021 Infineon Technologies AG
-* SPDX-License-Identifier: Apache-2.0
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-********************************************************************************/
+ * Copyright 2021 Infineon Technologies AG
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ********************************************************************************/
#if !(SWAP_DISABLED) && defined(UPGRADE_IMAGE)
#include "set_img_ok.h"
-#include "flash_qspi.h"
+#include <flash_map_backend/flash_map_backend.h>
+
+extern const struct flash_area_interface external_mem_interface;
static uint8_t row_buff[FLASH_ROW_BUF_SZ];
/**
* @brief Function reads value of img_ok flag from address.
- *
+ *
* @param address - address of img_ok flag in primary img trailer
* @return int - value at address
*/
+
static int read_img_ok_value(uint32_t address)
{
- uint32_t row_mask = qspi_get_erase_size() /* is a power of 2 */ - 1u;
- uint32_t row_addr = (address - CY_XIP_BASE) & ~row_mask;
+ uint8_t tmp;
+
+ external_mem_interface.read(0, address, &tmp, 1);
- cy_stc_smif_mem_config_t *cfg = qspi_get_memory_config(0);
- cy_en_smif_status_t st = Cy_SMIF_MemRead(qspi_get_device(), cfg,
- row_addr, row_buff, qspi_get_erase_size(),
- qspi_get_context());
- if (CY_SMIF_SUCCESS == st) {
- return row_buff[address & row_mask];
- }
-
- return -1;
+ return tmp;
}
+
/**
* @brief Function sets img_ok flag value to primary image trailer.
- *
+ *
* @param address - address of img_ok flag in primary img trailer
* @param value - value corresponding to img_ok set
- *
+ *
* @return - operation status. 0 - set succesfully, -1 - failed to set.
*/
+
static int write_img_ok_value(uint32_t address, uint8_t src)
{
- int rc = -1;
- uint32_t row_addr = 0;
-
- cy_stc_smif_mem_config_t *cfg = qspi_get_memory_config(0);
- uint32_t row_mask = qspi_get_erase_size() /* is a power of 2 */ - 1u;
- cy_en_smif_status_t st;
-
+ int rc = 0;
/* Accepting an arbitrary address */
- row_addr = (address - CY_XIP_BASE) & ~row_mask;
+ uint32_t row_mask = external_mem_interface.get_erase_size(0) - 1U;
- /* Preserving the block */
- st = Cy_SMIF_MemRead(qspi_get_device(), cfg,
- row_addr, row_buff, qspi_get_erase_size(),
- qspi_get_context());
+ rc |= external_mem_interface.read(0, address & ~row_mask, row_buff, FLASH_ROW_BUF_SZ);
- if (CY_SMIF_SUCCESS == st) {
- /* Modifying the target byte */
- row_buff[address & row_mask] = src;
+ /* Modifying the target byte */
+ row_buff[address & row_mask] = src;
- /* Programming the updated block back */
- st = Cy_SMIF_MemEraseSector(qspi_get_device(), cfg,
- row_addr, qspi_get_erase_size(),
- qspi_get_context());
+ rc |= external_mem_interface.erase(0, address & ~row_mask, FLASH_ROW_BUF_SZ);
- if (CY_SMIF_SUCCESS == st) {
- st = Cy_SMIF_MemWrite(qspi_get_device(), cfg,
- row_addr, row_buff, qspi_get_erase_size(),
- qspi_get_context());
- }
- }
-
- if (CY_SMIF_SUCCESS == st) {
- rc = 0;
- }
+ rc |= external_mem_interface.write(0, address & ~row_mask, row_buff, FLASH_ROW_BUF_SZ);
return rc;
}
+
/**
* @brief Public function to confirm that upgraded application is operable
- * after swap. Should be called from main code of user application.
+ * after swap. Should be called from main code of user application.
* It sets mcuboot flag img_ok in primary (boot) image trailer.
* MCUBootApp checks img_ok flag at first reset after upgrade and
* validates successful swap.
- *
+ *
* @param address - address of img_ok flag in primary img trailer
* @param value - value corresponding to img_ok set
- *
+ *
* @return - operation status. 1 - already set, 0 - set succesfully,
* -1 - failed to set.
*/
+
int set_img_ok(uint32_t address, uint8_t value)
{
int32_t rc = -1;
if (read_img_ok_value(address) != value) {
rc = write_img_ok_value(address, value);
- }
- else {
+ } else {
rc = IMG_OK_ALREADY_SET;
}
return rc;
}
+
#endif /* !(SWAP_DISABLED) && defined(UPGRADE_IMAGE) */
diff --git a/boot/cypress/platforms/memory/CYW20829/flash_qspi/flash_qspi.c b/boot/cypress/platforms/memory/CYW20829/flash_qspi/flash_qspi.c
index 120aab4..76ee0e7 100644
--- a/boot/cypress/platforms/memory/CYW20829/flash_qspi/flash_qspi.c
+++ b/boot/cypress/platforms/memory/CYW20829/flash_qspi/flash_qspi.c
@@ -220,7 +220,7 @@
/* The size allocated in the PSoC memory map, for the memory slave device.
The size is allocated from the base address. Valid when the memory mapped mode is enabled. */
/* .memMappedSize = 0x4000000U, */
- .flags = CY_SMIF_FLAG_DETECT_SFDP,
+ .flags = CY_SMIF_FLAG_DETECT_SFDP | CY_SMIF_FLAG_MEMORY_MAPPED | CY_SMIF_FLAG_CRYPTO_ENABLE,
.slaveSelect = CY_SMIF_SLAVE_SELECT_0,
.dataSelect = CY_SMIF_DATA_SEL0,
.deviceCfg = &dev_sfdp_0
@@ -436,20 +436,26 @@
CY_RAMFUNC_END /* SMIF will be deinitialized in this case! */
#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
+CY_RAMFUNC_BEGIN
cy_stc_smif_mem_config_t *qspi_get_memory_config(uint8_t index)
{
return smif_blk_config->memConfig[index];
}
+CY_RAMFUNC_END
+CY_RAMFUNC_BEGIN
SMIF_Type *qspi_get_device(void)
{
return QSPIPort;
}
+CY_RAMFUNC_END
+CY_RAMFUNC_BEGIN
cy_stc_smif_context_t *qspi_get_context(void)
{
return &QSPI_context;
}
+CY_RAMFUNC_END
cy_en_smif_status_t qspi_init(cy_stc_smif_block_config_t *blk_config)
{
diff --git a/boot/cypress/platforms/memory/PSOC6/internal_memory.c b/boot/cypress/platforms/memory/PSOC6/internal_memory.c
index 28ffe4b..c0d2d0e 100644
--- a/boot/cypress/platforms/memory/PSOC6/internal_memory.c
+++ b/boot/cypress/platforms/memory/PSOC6/internal_memory.c
@@ -55,6 +55,13 @@
return INTERNAL_MEMORY_ERASE_SIZE_PLATFORM;
}
+static uint32_t get_align_size(uint8_t fa_device_id)
+{
+ (void)fa_device_id;
+
+ return INTERNAL_MEMORY_ERASE_SIZE_PLATFORM;
+}
+
static uint8_t get_erase_val(uint8_t fa_device_id)
{
(void) fa_device_id;
@@ -198,4 +205,5 @@
.erase = &erase,
.get_erase_val = &get_erase_val,
.get_erase_size = &get_min_erase_size,
+ .get_align_size = &get_align_size,
.get_base_address = &get_base_address};
diff --git a/boot/cypress/platforms/memory/XMC7000/internal_memory_code.c b/boot/cypress/platforms/memory/XMC7000/internal_memory_code.c
index 4ba5fea..52070c0 100644
--- a/boot/cypress/platforms/memory/XMC7000/internal_memory_code.c
+++ b/boot/cypress/platforms/memory/XMC7000/internal_memory_code.c
@@ -31,6 +31,11 @@
return flash_devices[fa_device_id].erase_size;
}
+static uint32_t get_align_size(uint8_t fa_device_id)
+{
+ return flash_devices[fa_device_id].erase_size;
+}
+
static uint8_t get_erase_val(uint8_t fa_device_id)
{
return flash_devices[fa_device_id].erase_val;
@@ -163,4 +168,5 @@
.erase = &erase,
.get_erase_val = &get_erase_val,
.get_erase_size = &get_min_erase_size,
+ .get_align_size = &get_align_size,
.get_base_address = &get_base_address};
diff --git a/boot/cypress/platforms/memory/XMC7000/internal_memory_work.c b/boot/cypress/platforms/memory/XMC7000/internal_memory_work.c
index 0886985..998c975 100644
--- a/boot/cypress/platforms/memory/XMC7000/internal_memory_work.c
+++ b/boot/cypress/platforms/memory/XMC7000/internal_memory_work.c
@@ -38,6 +38,11 @@
return flash_devices[fa_device_id].erase_size;
}
+static uint32_t get_align_size(uint8_t fa_device_id)
+{
+ return flash_devices[fa_device_id].erase_size;
+}
+
static uint8_t get_erase_val(uint8_t fa_device_id)
{
return flash_devices[fa_device_id].erase_val;
@@ -178,4 +183,5 @@
.erase = &erase,
.get_erase_val = &get_erase_val,
.get_erase_size = &get_min_erase_size,
+ .get_align_size = &get_align_size,
.get_base_address = &get_base_address};
diff --git a/boot/cypress/platforms/memory/cy_flash_map.c b/boot/cypress/platforms/memory/cy_flash_map.c
index 451cdd2..b818724 100644
--- a/boot/cypress/platforms/memory/cy_flash_map.c
+++ b/boot/cypress/platforms/memory/cy_flash_map.c
@@ -184,7 +184,7 @@
size_t rc = 0u; /* error code (alignment cannot be zero) */
if ((fa != NULL) && (flash_area_get_api(fa->fa_device_id) != NULL)) {
- rc = flash_area_get_api(fa->fa_device_id)->get_erase_size(fa->fa_device_id);
+ rc = flash_area_get_api(fa->fa_device_id)->get_align_size(fa->fa_device_id);
}
return rc;
diff --git a/boot/cypress/platforms/memory/external_memory/external_memory.c b/boot/cypress/platforms/memory/external_memory/external_memory.c
index c9a58ff..5fe2b93 100644
--- a/boot/cypress/platforms/memory/external_memory/external_memory.c
+++ b/boot/cypress/platforms/memory/external_memory/external_memory.c
@@ -57,6 +57,21 @@
#include "flash_map_backend_platform.h"
#include "flash_qspi.h"
+#define SMIF_OFFSET(addr) ((uint32_t)(addr) - SMIF_MEM_START_PLATFORM)
+
+#if defined(MCUBOOT_ENC_IMAGES_SMIF)
+#define CY_GET_XIP_REMAP_ADDR(addr) ((addr) - CY_XIP_BASE + CY_XIP_CBUS_BASE)
+#define ICACHE_INVALIDATE() \
+ ({ \
+ /* Invalidate the cache */ \
+ ICACHE0->CMD = ICACHE0->CMD | ICACHE_CMD_INV_Msk; \
+ \
+ /*Wait for invalidation complete */ \
+ while (ICACHE0->CMD & ICACHE_CMD_INV_Msk); \
+ })
+
+#endif
+
static uint32_t get_base_address(uint8_t fa_device_id)
{
uint32_t res = 0U;
@@ -78,6 +93,17 @@
return qspi_get_erase_size();
}
+static uint32_t get_align_size(uint8_t fa_device_id)
+{
+ (void)fa_device_id;
+
+#if !defined(MCUBOOT_SWAP_USING_STATUS)
+ return sizeof(uint32_t);
+#else
+ return qspi_get_erase_size();
+#endif
+}
+
static uint8_t get_erase_val(uint8_t fa_device_id)
{
(void)fa_device_id;
@@ -89,6 +115,20 @@
{
(void)fa_device_id;
+#if defined(MCUBOOT_ENC_IMAGES_SMIF)
+ uintptr_t src = CY_GET_XIP_REMAP_ADDR(addr);
+ size_t mem_sz = qspi_get_mem_size();
+
+ if ((src >= CY_XIP_CBUS_BASE) && (src <= (CY_XIP_CBUS_BASE + mem_sz))) {
+ if ((src + len) <= (CY_XIP_CBUS_BASE + mem_sz)) {
+ memcpy(data, (const void *)src, len);
+
+ return 0;
+ }
+ }
+ return -1;
+#else
+
int rc = -1;
cy_stc_smif_mem_config_t *cfg;
cy_en_smif_status_t st;
@@ -104,74 +144,130 @@
rc = 0;
}
return rc;
+#endif
}
+CY_RAMFUNC_BEGIN
+static cy_en_smif_status_t smif_write(uint32_t offset, const void *data, size_t len)
+{
+ SMIF_Type *device = qspi_get_device();
+ cy_stc_smif_context_t *ctx = qspi_get_context();
+ cy_stc_smif_mem_config_t *cfg = qspi_get_memory_config(0u);
+
+ return Cy_SMIF_MemWrite(device, cfg, offset, data, len, ctx);
+}
+CY_RAMFUNC_END
+
+#if defined(MCUBOOT_ENC_IMAGES_SMIF)
+CY_RAMFUNC_BEGIN
+static cy_en_smif_status_t smif_encrypt(const void *data, uint32_t len, uintptr_t addr)
+{
+ cy_en_smif_status_t status = CY_SMIF_SUCCESS;
+ SMIF_Type *device = qspi_get_device();
+ cy_stc_smif_context_t *ctx = qspi_get_context();
+
+ Cy_SMIF_SetMode(device, CY_SMIF_NORMAL);
+ status = Cy_SMIF_Encrypt(device, CY_GET_XIP_REMAP_ADDR(addr), data, len, ctx);
+ Cy_SMIF_SetMode(device, CY_SMIF_MEMORY);
+
+ return status;
+}
+CY_RAMFUNC_END
+
+CY_RAMFUNC_BEGIN
+static cy_en_smif_status_t
+smif_write_encrypt_block(const void **data, uint32_t *len, uintptr_t *addr)
+{
+ cy_en_smif_status_t status = CY_SMIF_SUCCESS;
+ uintptr_t write_address = *addr;
+ uintptr_t prev_align = write_address & CY_SMIF_CRYPTO_ADDR_MASK;
+ uintptr_t next_align = prev_align + CY_SMIF_AES128_BYTES;
+ size_t align_offset = write_address - prev_align;
+ uint8_t tmp[CY_SMIF_AES128_BYTES] = {0U};
+ size_t bytes_to_cpy = *len;
+
+ if ((*len) > CY_SMIF_AES128_BYTES) {
+ bytes_to_cpy = CY_SMIF_AES128_BYTES - ((*len) % CY_SMIF_AES128_BYTES);
+ }
+
+ (void)memcpy((void *)&tmp[align_offset], *data, bytes_to_cpy);
+
+ status = smif_encrypt(tmp, CY_SMIF_AES128_BYTES, prev_align);
+
+ if (status == CY_SMIF_SUCCESS) {
+ status = smif_write(SMIF_OFFSET(write_address), &tmp[align_offset], bytes_to_cpy);
+ }
+
+ if (status == CY_SMIF_SUCCESS) {
+ *len -= bytes_to_cpy;
+ *addr = next_align;
+ *data = &((uint8_t *)(*data))[bytes_to_cpy];
+ }
+
+ return status;
+}
+CY_RAMFUNC_END
+#endif
+
+CY_RAMFUNC_BEGIN
static int write(uint8_t fa_device_id, uintptr_t addr, const void *data,
uint32_t len)
{
(void)fa_device_id;
- int rc = -1;
- cy_en_smif_status_t st = CY_SMIF_SUCCESS;
- cy_stc_smif_mem_config_t *cfg;
- uint32_t offset;
+ int rc = -1;
+ cy_en_smif_status_t status = CY_SMIF_SUCCESS;
+ const void *p_data = data;
- cfg = qspi_get_memory_config(0u);
-
- offset = (uint32_t)addr - SMIF_MEM_START_PLATFORM;
-
-#if defined CYW20829
- st = Cy_SMIF_MemEraseSector(qspi_get_device(), cfg, offset,
- qspi_get_erase_size(), qspi_get_context());
-
- if (st == CY_SMIF_SUCCESS) {
-#endif /* CYW20829 */
- st = Cy_SMIF_MemWrite(qspi_get_device(), cfg, offset, data, len,
- qspi_get_context());
-#if defined CYW20829
+#if defined(MCUBOOT_ENC_IMAGES_SMIF)
+ while ((len > 0U) && (status == CY_SMIF_SUCCESS)) {
+ status = smif_write_encrypt_block(&p_data, &len, &addr);
}
+#else
+ status = smif_write(SMIF_OFFSET(addr), p_data, len);
#endif
- if (st == CY_SMIF_SUCCESS) {
- rc = 0;
- }
+
+#if defined(MCUBOOT_ENC_IMAGES_SMIF)
+ ICACHE_INVALIDATE();
+#endif
+
+ rc = (status == CY_SMIF_SUCCESS) ? 0 : -1;
+
return rc;
}
+CY_RAMFUNC_END
+CY_RAMFUNC_BEGIN
static int erase(uint8_t fa_device_id, uintptr_t addr, uint32_t size)
{
(void)fa_device_id;
- int rc = -1;
- cy_en_smif_status_t st = CY_SMIF_SUCCESS;
- uint32_t offset;
+ int rc = -1;
if (size > 0u) {
- /* It is erase sector-only
- *
- * There is no power-safe way to erase flash partially
- * this leads upgrade slots have to be at least
- * eraseSectorSize far from each other;
- */
- cy_stc_smif_mem_config_t *memCfg = qspi_get_memory_config(0);
- uint32_t eraseSize = qspi_get_erase_size();
+ SMIF_Type *device = qspi_get_device();
+ cy_stc_smif_context_t *ctx = qspi_get_context();
+ cy_stc_smif_mem_config_t *cfg = qspi_get_memory_config(0u);
+ uint32_t eraseSize = qspi_get_erase_size();
+ uint32_t offset = ((uint32_t)addr - SMIF_MEM_START_PLATFORM) & ~((uint32_t)(eraseSize - 1u));
- offset = ((uint32_t)addr - SMIF_MEM_START_PLATFORM) & ~((uint32_t)(eraseSize - 1u));
-
- while ((size > 0u) && (CY_SMIF_SUCCESS == st)) {
- st = Cy_SMIF_MemEraseSector(qspi_get_device(), memCfg, offset,
- eraseSize, qspi_get_context());
-
+ while ((size > 0u) && (CY_SMIF_SUCCESS == Cy_SMIF_MemEraseSector(device, cfg, offset, eraseSize, ctx))) {
size -= (size >= eraseSize) ? eraseSize : size;
offset += eraseSize;
}
- if (st == CY_SMIF_SUCCESS) {
+ if (size == 0) {
rc = 0;
}
}
+#if defined(MCUBOOT_ENC_IMAGES_SMIF)
+ ICACHE_INVALIDATE();
+#endif
+
return rc;
}
+CY_RAMFUNC_END
static int open(uint8_t fa_device_id)
{
@@ -186,11 +282,12 @@
}
const struct flash_area_interface external_mem_interface = {
- .open = &open,
- .close = &close,
- .read = &read,
- .write = &write,
- .erase = &erase,
- .get_erase_val = &get_erase_val,
- .get_erase_size = &get_min_erase_size,
+ .open = &open,
+ .close = &close,
+ .read = &read,
+ .write = &write,
+ .erase = &erase,
+ .get_erase_val = &get_erase_val,
+ .get_erase_size = &get_min_erase_size,
+ .get_align_size = &get_align_size,
.get_base_address = &get_base_address};
diff --git a/boot/cypress/platforms/memory/flash_map_backend/flash_map_backend.h b/boot/cypress/platforms/memory/flash_map_backend/flash_map_backend.h
index 13002c3..c882a97 100644
--- a/boot/cypress/platforms/memory/flash_map_backend/flash_map_backend.h
+++ b/boot/cypress/platforms/memory/flash_map_backend/flash_map_backend.h
@@ -59,6 +59,7 @@
int (*erase)(uint8_t fa_device_id, uintptr_t addr, uint32_t len);
uint8_t (*get_erase_val)(uint8_t fa_device_id);
uint32_t (*get_erase_size)(uint8_t fa_device_id);
+ uint32_t (*get_align_size)(uint8_t fa_device_id);
uint32_t (*get_base_address)(uint8_t fa_device_id);
};
diff --git a/boot/cypress/toolchains.mk b/boot/cypress/toolchains.mk
index 9fe6191..7f5d771 100644
--- a/boot/cypress/toolchains.mk
+++ b/boot/cypress/toolchains.mk
@@ -39,7 +39,7 @@
# NOTE: Absolute pathes for now for the sake of development
ifeq ($(HOST_OS), win)
ifeq ($(COMPILER), GCC_ARM)
- TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox/tools_3.1/gcc
+ TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox/tools_3.2/gcc
MY_TOOLCHAIN_PATH := $(call get_os_path, $(TOOLCHAIN_PATH))
TOOLCHAIN_PATH := $(MY_TOOLCHAIN_PATH)
GCC_PATH := $(TOOLCHAIN_PATH)