3939int WP11_Library_Init (void );
4040#endif
4141
42+ #ifdef EXT_ENCRYPTED
43+ #include "encrypt.h"
44+ #endif /* EXT_ENCRYPTED */
45+
4246#ifdef RAM_CODE
4347#ifndef TARGET_rp2350
4448extern unsigned int _start_text ;
@@ -55,9 +59,6 @@ static uint8_t buffer[FLASHBUFFER_SIZE] XALIGNED(4);
5559# endif
5660#endif
5761
58- #ifdef EXT_ENCRYPTED
59- #include "encrypt.h"
60- #endif
6162
6263static void RAMFUNCTION wolfBoot_erase_bootloader (void )
6364{
@@ -136,6 +137,7 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src,
136137 uint32_t src_sector_offset = (sector * WOLFBOOT_SECTOR_SIZE );
137138 uint32_t dst_sector_offset = src_sector_offset ;
138139#ifdef EXT_ENCRYPTED
140+ uint32_t i ;
139141 uint8_t key [ENCRYPT_KEY_SIZE ];
140142 uint8_t nonce [ENCRYPT_NONCE_SIZE ];
141143 uint32_t iv_counter ;
@@ -153,19 +155,21 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src,
153155 dst_sector_offset = 0 ;
154156
155157#ifdef EXT_ENCRYPTED
156- if (wolfBoot_initialize_encryption () < 0 ) {
158+ if (wolfBoot_initialize_encryption () < 0 )
157159 return -1 ;
158- }
159- wolfBoot_get_encrypt_key (key , nonce );
160160
161+ wolfBoot_get_encrypt_key (key , nonce );
161162 if (src -> part == PART_SWAP )
162163 iv_counter = dst_sector_offset ;
163164 else
165+ /*
166+ * Always re-derive the IV starting from the source address.
167+ * This guarantees we do not reuse the same IV in the SWAP partition.
168+ */
164169 iv_counter = src_sector_offset ;
165-
166170 iv_counter /= ENCRYPT_BLOCK_SIZE ;
167- crypto_set_iv (nonce , iv_counter );
168- #endif
171+ wolfBoot_crypto_set_iv (nonce , iv_counter );
172+ #endif /* EXT_ENCRYPTED */
169173
170174#ifdef EXT_FLASH
171175 if (PART_IS_EXT (src )) {
@@ -222,7 +226,6 @@ static int RAMFUNCTION wolfBoot_backup_last_boot_sector(uint32_t sector)
222226 wolfBoot_open_image (src , PART_BOOT );
223227 wolfBoot_open_image (dst , PART_SWAP );
224228
225-
226229 wolfBoot_printf ("Copy sector %d (part %d->%d)\n" ,
227230 sector , src -> part , dst -> part );
228231
@@ -234,7 +237,12 @@ static int RAMFUNCTION wolfBoot_backup_last_boot_sector(uint32_t sector)
234237 iv_counter /= ENCRYPT_BLOCK_SIZE ;
235238 if (wolfBoot_initialize_encryption () < 0 )
236239 return -1 ;
237- crypto_set_iv (nonce , iv_counter );
240+ /*
241+ * Preserve the IV sequence used by the source sector so that the staging
242+ * copy in SWAP can be decrypted with exactly the same keystream when it is
243+ * restored to BOOT.
244+ */
245+ wolfBoot_crypto_set_iv (nonce , iv_counter );
238246
239247 /* Erase swap space */
240248 wb_flash_erase (dst , dst_sector_offset , WOLFBOOT_SECTOR_SIZE );
@@ -523,7 +531,7 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
523531 }
524532 iv_counter /= ENCRYPT_BLOCK_SIZE ;
525533 /* Encrypt + send */
526- crypto_set_iv (nonce , iv_counter );
534+ wolfBoot_crypto_set_iv (nonce , iv_counter );
527535 crypto_encrypt (enc_blk , delta_blk , ret );
528536 wr_ret = ext_flash_write (
529537 (uint32_t )(WOLFBOOT_PARTITION_SWAP_ADDRESS + len ),
@@ -659,26 +667,54 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
659667 uint16_t update_type ;
660668 uint32_t fw_size ;
661669 uint32_t size ;
670+ int inverse = 0 ;
671+ int fallback_image = 0 ;
662672#if defined(DISABLE_BACKUP ) && defined(EXT_ENCRYPTED )
663673 uint8_t key [ENCRYPT_KEY_SIZE ];
664674 uint8_t nonce [ENCRYPT_NONCE_SIZE ];
665675#endif
666676#ifdef DELTA_UPDATES
667677 uint8_t st ;
668- int inverse = 0 ;
669678 int resume = 0 ;
670679 int stateRet = -1 ;
671- uint32_t cur_v ;
672- uint32_t up_v ;
673680#endif
674681 uint32_t cur_ver , upd_ver ;
675682
676683 wolfBoot_printf ("Staring Update (fallback allowed %d)\n" , fallback_allowed );
677684
678685 /* No Safety check on open: we might be in the middle of a broken update */
679- wolfBoot_open_image (& update , PART_UPDATE );
680- wolfBoot_open_image (& boot , PART_BOOT );
681- wolfBoot_open_image (& swap , PART_SWAP );
686+ {
687+ int update_open ;
688+ #ifdef EXT_ENCRYPTED
689+ /* Start with the standard IV mapping for every fresh update attempt. */
690+ wolfBoot_enable_fallback_iv (0 );
691+ #endif
692+ update_open = wolfBoot_open_image (& update , PART_UPDATE );
693+ #ifdef EXT_ENCRYPTED
694+ if (update_open < 0 ) {
695+ int prev = wolfBoot_enable_fallback_iv (1 );
696+ (void )prev ;
697+ update_open = wolfBoot_open_image (& update , PART_UPDATE );
698+ if (update_open < 0 ) {
699+ wolfBoot_enable_fallback_iv (0 );
700+ return -1 ;
701+ }
702+ fallback_image = 1 ;
703+ }
704+ wolfBoot_enable_fallback_iv (fallback_image );
705+ #else
706+ if (update_open < 0 )
707+ return -1 ;
708+ #endif
709+ wolfBoot_open_image (& boot , PART_BOOT );
710+ wolfBoot_open_image (& swap , PART_SWAP );
711+
712+ #ifdef EXT_ENCRYPTED
713+ wolfBoot_printf ("Update partition fallback image: %d\n" , fallback_image );
714+ if (fallback_image )
715+ inverse = 1 ;
716+ #endif
717+ }
682718
683719 /* get total size */
684720 total_size = wolfBoot_get_total_size (& boot , & update );
@@ -705,12 +741,23 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
705741 wolfBoot_printf ("Invalid update size %u\n" , update .fw_size );
706742 return -1 ;
707743 }
708- if (!update .hdr_ok
709- || (wolfBoot_verify_integrity (& update ) < 0 )
710- || (wolfBoot_verify_authenticity (& update ) < 0 )) {
711- wolfBoot_printf ("Update verify failed: Hdr %d, Hash %d, Sig %d\n" ,
712- update .hdr_ok , update .sha_ok , update .signature_ok );
713- return -1 ;
744+ if (!fallback_image ) {
745+ if (!update .hdr_ok
746+ || (wolfBoot_verify_integrity (& update ) < 0 )
747+ || (wolfBoot_verify_authenticity (& update ) < 0 )) {
748+ wolfBoot_printf ("Update verify failed: Hdr %d, Hash %d, Sig %d\n" ,
749+ update .hdr_ok , update .sha_ok , update .signature_ok );
750+ return -1 ;
751+ }
752+ } else {
753+ /*
754+ * When we recover an already-encrypted fallback image, the
755+ * manifest still contains hashes computed with the original IV
756+ * stream. Skip the redundant integrity/authenticity checks here
757+ * and let the bootloader verify the restored image after the swap.
758+ */
759+ update .sha_ok = 1 ;
760+ update .signature_ok = 1 ;
714761 }
715762 PART_SANITY_CHECK (& update );
716763
@@ -731,12 +778,11 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
731778 }
732779#endif
733780 }
781+ if (cur_ver > upd_ver )
782+ inverse = 1 ;
734783
735784#ifdef DELTA_UPDATES
736785 if ((update_type & 0x00F0 ) == HDR_IMG_TYPE_DIFF ) {
737- cur_v = wolfBoot_current_firmware_version ();
738- up_v = wolfBoot_update_firmware_version ();
739- inverse = cur_v >= up_v ;
740786 /* if magic isn't set stateRet will be -1 but that means we're on a
741787 * fresh partition and aren't resuming */
742788 stateRet = wolfBoot_get_partition_state (PART_UPDATE , & st );
@@ -745,7 +791,7 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
745791 * header we can't determine the direction by version numbers. instead
746792 * use the update partition state, updating means regular, new means
747793 * reverting */
748- if ((stateRet == 0 ) && ((flag != SECT_FLAG_NEW ) || (cur_v == 0 ))) {
794+ if ((stateRet == 0 ) && ((flag != SECT_FLAG_NEW ) || (cur_ver == 0 ))) {
749795 resume = 1 ;
750796 if (st == IMG_STATE_UPDATING ) {
751797 inverse = 0 ;
@@ -780,7 +826,6 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
780826 #ifdef EXT_FLASH
781827 ext_flash_unlock ();
782828 #endif
783-
784829 /* Interruptible swap
785830 * The status is saved in the sector flags of the update partition.
786831 * If something goes wrong, the operation will be resumed upon reboot.
@@ -800,7 +845,22 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
800845 if (size > sector_size )
801846 size = sector_size ;
802847 flag = SECT_FLAG_BACKUP ;
803- wolfBoot_copy_sector (& boot , & update , sector );
848+ {
849+ #ifdef EXT_ENCRYPTED
850+ /*
851+ * When we are performing a fallback, force the alternate
852+ * IV offset only for the segment copied from BOOT into
853+ * UPDATE. All other copies see the offset that was
854+ * active beforehand (0 for the normal path, fallback
855+ * offset for the recovery path).
856+ */
857+ int prev_iv = wolfBoot_enable_fallback_iv (1 );
858+ #endif
859+ wolfBoot_copy_sector (& boot , & update , sector );
860+ #ifdef EXT_ENCRYPTED
861+ wolfBoot_enable_fallback_iv (prev_iv );
862+ #endif
863+ }
804864 if (((sector + 1 ) * sector_size ) < WOLFBOOT_PARTITION_SIZE )
805865 wolfBoot_set_update_sector_flag (sector , flag );
806866 /* FALL THROUGH */
@@ -945,10 +1005,14 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
9451005 hal_flash_lock ();
9461006
9471007 /* Save the encryption key after swapping */
948- #ifdef EXT_ENCRYPTED
1008+ #ifdef EXT_ENCRYPTED
9491009 wolfBoot_set_encrypt_key (key , nonce );
950- #endif
1010+ #endif
9511011#endif /* DISABLE_BACKUP */
1012+ #ifdef EXT_ENCRYPTED
1013+ /* Make sure we leave the global IV offset in its normal state. */
1014+ wolfBoot_enable_fallback_iv (0 );
1015+ #endif
9521016 return 0 ;
9531017}
9541018
0 commit comments