Skip to content

Conversation

@danielinux
Copy link
Member

@danielinux danielinux commented Jan 12, 2026

ARMORED=1

  • Improved fault mitigation: more redundancy, hardened
  • Added redundancy to ML_DSA verification

STM32_TZ SAU:

  • Set UPDATE partition to secure. It is only accessed via NSC when the application is running
  • flash_top_secure in hal_tz_sau_init to the same range

Fixes:

  • Bug preventing rollback in case of ARMORED=1.
  • rolled-back image state handling: force update flags on rollback. Set success after complete rollback.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances fault mitigation in ARMORED mode with improved redundancy checks, adds ARMORED support for ML_DSA signature verification, fixes rollback handling bugs, and reconfigures STM32 TrustZone SAU regions to set the UPDATE partition as secure.

Changes:

  • Enhanced ARMORED mode with additional redundancy in signature verification and version checking
  • Added redundant verification checks for ML_DSA signatures when ARMORED=1
  • Fixed rollback logic to properly handle version checks and state transitions with ARMORED enabled
  • Reconfigured STM32_TZ SAU to mark UPDATE partition as secure and adjusted flash region mappings

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tools/test.mk Updated size limits for test targets to accommodate increased code size from ARMORED enhancements
src/update_flash.c Added rollback detection logic, refactored version check to work with ARMORED, and improved rollback state handling
src/image.c Added ARMORED redundancy checks to ML_DSA verification and updated signature verification macros
include/image.h Refactored VERIFY_VERSION_ALLOWED macro for both GCC and IAR with improved redundancy and changed signed to unsigned comparisons
hal/stm32_tz.c Reconfigured SAU regions to mark UPDATE partition as secure with dynamic flash_top_secure calculation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

"b .\n" \
"2:\n" \
"pop {r4, r5, r6, r7}\n" \
: /* No output operands */ \
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The clobbered registers list for the IAR version is missing 'lr', 'cc', and 'memory' compared to the GCC version on line 620. Since this inline assembly calls functions with 'bl' instructions (which modifies 'lr') and performs comparisons (which modifies condition codes), these should be included in the clobber list to ensure the compiler preserves these registers correctly.

Copilot uses AI. Check for mistakes.
Comment on lines +546 to +556
"mov r0, %0\n" \
"mov r4, %0\n" \
"cmp r0, #1\n" \
"bne do_check\n" \
"cmp r4, #1\n" \
"bne do_check\n" \
"cmp r0, r4\n" \
"bne do_check\n" \
"cmp r0, #1\n" \
"bne do_check\n" \
"b end_check\n" \
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IAR version includes additional validation checks (lines 641-651) that trigger breakpoints if fb_ok is neither 0 nor 1, while the GCC version (lines 546-556) does not have equivalent validation. This inconsistency means the two compiler paths have different security hardening levels. Consider adding similar validation to the GCC version for consistency.

Copilot uses AI. Check for mistakes.
Comment on lines +304 to +315
/* Non-secure flash alias (entire NS flash window) */
sau_init_region(1, 0x08000000, FLASH_TOP, 0);

/* Secure: update partition in secure alias (use matching FLASH_TOP base) */
uint32_t flash_top_secure = FLASH_TOP;
if ((WOLFBOOT_PARTITION_UPDATE_ADDRESS & 0xFF000000u) !=
(FLASH_TOP & 0xFF000000u)) {
flash_top_secure =
(WOLFBOOT_PARTITION_UPDATE_ADDRESS & 0xFF000000u) |
(FLASH_TOP & 0x00FFFFFFu);
}
sau_init_region(2, WOLFBOOT_PARTITION_UPDATE_ADDRESS, flash_top_secure, 1);
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SAU configuration has been significantly changed. Region 1 now covers the entire flash window (0x08000000 to FLASH_TOP) as non-secure, while Region 2 marks only the UPDATE partition as secure. This means the BOOT partition is now accessible as non-secure via Region 1. Verify this is the intended behavior and that the BOOT partition doesn't need secure access protection during runtime. The description states the UPDATE partition is only accessed via NSC, but this configuration change may have broader security implications.

Copilot uses AI. Check for mistakes.
@danielinux danielinux requested a review from rizlik January 12, 2026 11:42
/* Secure: application flash area (second bank) */
sau_init_region(2, WOLFBOOT_PARTITION_UPDATE_ADDRESS, FLASH_TOP, 0);
/* Non-secure flash alias (entire NS flash window) */
sau_init_region(1, 0x08000000, FLASH_TOP, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: can you use a constant instead of 0x08000000?

Comment on lines +308 to +314
uint32_t flash_top_secure = FLASH_TOP;
if ((WOLFBOOT_PARTITION_UPDATE_ADDRESS & 0xFF000000u) !=
(FLASH_TOP & 0xFF000000u)) {
flash_top_secure =
(WOLFBOOT_PARTITION_UPDATE_ADDRESS & 0xFF000000u) |
(FLASH_TOP & 0x00FFFFFFu);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I"m slightly confused here, if the FLASH_TOP is also the top of WOLFBOOT_PARTITION_UPDATE_ADDRESS then flash_top_secure stores the top bit only, otherwise it stores the full address. Is it on purpose?

(WOLFBOOT_PARTITION_UPDATE_ADDRESS & 0xFF000000u) |
(FLASH_TOP & 0x00FFFFFFu);
}
sau_init_region(2, WOLFBOOT_PARTITION_UPDATE_ADDRESS, flash_top_secure, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes the region NSC, not secure as mentioned by the comment on line 307

"bhs ver_panic\n" \
"b end_check\n" \
"ver_panic:\n" \
"b .\n" \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need multiple b. here

"bhs 3f\n" \
"b 2f\n" \
"3:\n" \
"b .\n" \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

"beq 4f\n" \
"bkpt 0xE1\n" \
"4:\n" \
"cmp r4, #0\n" \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you think cmp cmp cmp cmp beq beq beq beq is a more robust pattern?

#endif
int fallback_image = 0;
#ifndef DISABLE_BACKUP
int rollback = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: do you think it make sense to call it fallback or in_fallback to match fallback_allowed?

Comment on lines +802 to +805
{
uint32_t fb_ok = (fallback_allowed == 1);
VERIFY_VERSION_ALLOWED(fb_ok);
(void)fb_ok;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you elaborate the reason of the fb_ok aliasing here?

Comment on lines +1238 to +1250
if (updateRet != 0) {
hal_flash_unlock();
#ifdef EXT_FLASH
ext_flash_unlock();
#endif
wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_UPDATING);
#ifdef EXT_FLASH
ext_flash_lock();
#endif
hal_flash_lock();
updateRet = 0;
updateState = IMG_STATE_UPDATING;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the reason of this?

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