Skip to content

Conversation

@danielinux
Copy link
Member

As reported by @reza-hdd in #589:

When Firmware is large enough to consume all the allocated boot partition sectors, in the the final swap and erase operations (wolfBoot_swap_and_final_erase) the last sector of FW in Boot partition, which is used as a temporary sector for a copy operation, gets corrupted after being copied in external Swap partition and copied back. It looks like the contents are copied to the external Swap partition without being encrypted, but get decrypted when it is read back.

This was due to the function wolfBoot_copy_sector() assuming that all copies having an external SWAP as destination would not need any encryption, as the "normal" case during update is to copy already encrypted sectors from UPDATE->SWAP.

In the final state, after the update is successfully applied, the mechanism saves a copy of the last sector from BOOT->SWAP. In this case, if the application is big enough, an extra function is needed to encrypt the content of this last sector before writing it to SWAP.

Restoring the backup is OK (normal case SWAP->BOOT, decryption was already there as also noted by the reporter).

Testing

I was able to reproduce the issue in the simulator by applying the following patch to the test application:

diff --git a/test-app/app_sim.c b/test-app/app_sim.c
index e118e5a9..7446b763 100644
--- a/test-app/app_sim.c
+++ b/test-app/app_sim.c
@@ -41,6 +41,9 @@
 char enc_key[] = "0123456789abcdef0123456789abcdef"
                 "0123456789abcdef";
 
+#define FILLER_SIZE (0x16000 - 0x2000 - 0x400)
+static volatile uint8_t filler_data[FILLER_SIZE] = { 0x01, 0x02, 0x03 };
+
 #ifdef TEST_DELTA_DATA
 static volatile char __attribute__((used)) garbage[TEST_DELTA_DATA] = {0x01, 0x02, 0x03, 0x04 };
 
@@ -50,6 +53,7 @@ void hal_init(void);
 
 int do_cmd(const char *cmd)
 {
+    filler_data[FILLER_SIZE - 1] = 0xAA;
     if (strcmp(cmd, "powerfail") == 0) {
         return 1;
     }

FILLER_SIZE is arbitrary, and adjusted on my setup to produce a test image.bin as big to fill up to the third-last sector (sector size in sim= 0x1000, two sectors reserved for redundancy of NVM_FLASH_WRITEONCE workaround, 0x200 or 0x400 for manifest header).

I used the following configuration:

cp config/examples/sim-encrypt-nvm-writeonce-update.config .config

and built the test case for the update:

test-sim-external-flash-with-enc-update

Running the update test:

tools/scripts/sim-sunnyday-update.sh

Would fail on current master branch, as reported. With this fix the test is successful, and the last sector is encrypted during the backup step.

As reported by @reza-hdd in wolfSSL#589:

> When Firmware is large enough to consume all the allocated boot partition sectors, in the the final swap and erase operations (_wolfBoot_swap_and_final_erase_) the last sector of FW in Boot partition, which is used as a temporary sector for a copy operation, gets corrupted after being copied in external Swap partition and copied back. It looks like the contents are copied to the external Swap partition without being encrypted, but get decrypted when it is read back.

This was due to the function wolfBoot_copy_sector() assuming that all
copies having an external SWAP as destination would not need any
encryption, as the "normal" case during update is to copy already
encrypted sectors from UPDATE->SWAP.

In the final state, after the update is successfully applied, the
mechanism saves a copy of the last sector from BOOT->SWAP. In this case,
if the application is big enough, an extra function is needed to
encrypt the content of this last sector before writing it to SWAP.

Restoring the backup is OK (normal case SWAP->BOOT, decryption was
already there as also noted by the reporter).
@danielinux danielinux assigned rizlik and unassigned danielinux Sep 11, 2025
@rizlik rizlik assigned danielinux and unassigned rizlik Sep 11, 2025
@rizlik rizlik merged commit b0f0de9 into wolfSSL:master Sep 12, 2025
262 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants