Skip to content

Conversation

@sasdf
Copy link
Contributor

@sasdf sasdf commented Dec 18, 2025

This commit introduces a new dual-redundancy scheme for writing boot data to flash. Instead of the legacy circular writing scheme, which is now renamed to boot_data_write_old, the new boot_data_write function ensures that a valid and consistent entry is written to the first index of both boot data pages.

Key changes:

  • Renamed the legacy boot_data_write to boot_data_write_old (for compatibility testing).
  • Implemented the new boot_data_write using a dual-redundancy algorithm.
  • Added boot_data_redundancy_check to verify consistency between the two pages.
  • Updated rom_ext_start to automatically repair boot data using the redundancy check.

Size difference:

rom_ext size Δoriginal Δfeature
Original 52668 +0 +0
New boot_data_write 52604 -64 -64
 + redundancy fix 52756 +88 +152
(Features below could be omitted if size is a concern)
 + hardening 52804 +136 +48
 + two entries per page 52844 +176 +40
 + boot log event 52860 +192 +16

Coverage:

Full coverage of the added code is verified manually with the following command.

./bazelisk.sh coverage --config=ot_coverage \
  //sw/device/silicon_creator/lib:boot_data_functest_fpga_cw340_rom_with_fake_keys

genhtml -o /tmp/$USER/coverage --ignore-errors inconsistent,unsupported \
  bazel-out/_coverage/_coverage_report.dat

@sasdf sasdf force-pushed the mgTc31d8c3c branch 6 times, most recently from 7d4520f to 2963544 Compare December 23, 2025 06:47
@siemen11 siemen11 self-requested a review December 23, 2025 21:51
@sasdf sasdf force-pushed the mgTc31d8c3c branch 2 times, most recently from e53a867 to 15fdd4a Compare January 5, 2026 16:00
@sasdf sasdf marked this pull request as ready for review January 5, 2026 16:41
@sasdf sasdf requested a review from a team as a code owner January 5, 2026 16:41
Copy link
Contributor

@siemen11 siemen11 left a comment

Choose a reason for hiding this comment

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

Thank you for the changes to the ROM_EXT! These changes are highly important to secure the rollback mechanic of the boot.
However, if I understand correctly, if all boot_data entries are invalidated (the two indices per page and the two pages of boot_data), then the ROM_EXT will proceed with loading a default boot data (which has security version 0) to all copies in flash. This invalidation could have been done through adversarial means.
Given the attacker has an old BL0 (with a lower security version), this means that it can be correctly loaded giving a rollback.
Please let me know if I misunderstood the logic. Maybe we can discuss the change in a meeting?

@sasdf
Copy link
Contributor Author

sasdf commented Jan 7, 2026

if all boot_data entries are invalidated, ...

The update flow is designed to ensure that the inactive page is written and verified via read-back before the active page is updated. This guarantees that at least one valid entry is available at all times, preventing an unintended fallback to the default boot data.

With the new scheme, entries are categorized as either:

  1. Valid (with correct hashes)
  2. Invalid (erased, partially programmed, or physically corrupted)

In scenarios where a page becomes corrupted (e.g., due to power loss), we always write the new data to that corrupted page first. This makes it impossible to invalidate all entries simultaneously without a direct physical attack.

@sasdf sasdf force-pushed the mgTc31d8c3c branch 2 times, most recently from d224b34 to 56da5a0 Compare January 9, 2026 04:30
@cfrantz
Copy link
Contributor

cfrantz commented Jan 10, 2026

This change LGTM, but I'd really like to make sure there is a test to validate that the approach of writing two records to each page.

@sasdf sasdf force-pushed the mgTc31d8c3c branch 2 times, most recently from 8514d3d to a66a56f Compare January 13, 2026 14:07
@sasdf
Copy link
Contributor Author

sasdf commented Jan 13, 2026

Thanks. The latest commit introduced tests for various entry validity combinations within the page. The write_empty_test handles cases where all entries are invalid, while subsequent tests cover the remaining scenarios: invalid/valid, valid/invalid, and valid/valid.

Each of these tests reads back all four entries to verify that boot_data_write has updated all of them accordingly.

This commit introduces a new dual-redundancy scheme for writing boot
data to flash. Instead of the legacy circular writing scheme, which
is now renamed to `boot_data_write_old`, the new `boot_data_write`
function ensures that a valid and consistent entry is written to
the first index of both boot data pages.

Key changes:
- Renamed the legacy `boot_data_write` to `boot_data_write_old`.
- Implemented the new `boot_data_write` using a dual-redundancy
  algorithm.
- Added `boot_data_redundancy_check` to verify consistency between
  the two pages.
- Updated `rom_ext_start` to automatically repair boot data using
  the redundancy check.

Change-Id: Ic31d8c3c778397feb8eb2991ca9e670917047633
Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com>
@sasdf sasdf force-pushed the mgTc31d8c3c branch 2 times, most recently from 0f1663c to 1871921 Compare January 15, 2026 04:08
@sasdf sasdf requested a review from cfrantz January 15, 2026 08:06
@sasdf
Copy link
Contributor Author

sasdf commented Jan 15, 2026

In addition to the requested changes, I included two minor follow-up commits:

  • boot_data_check() during read-back verification to confirm that new data indeed verifies correctly, preventing a write from potentially invalidating all entries.
  • Ignore redundancy fix error codes in ROM_EXT to avoid non-rescuable boot loops.

sasdf added 5 commits January 16, 2026 09:23
In addition to using hardened functions for control flow integrity, this
change updates `boot_data_write` to write each entry twice per page
(at index 0 and 1). This redundancy ensures that the boot data can
survive some types of persistent bit corruption.

Change-Id: I548174aba322da3b5bf7c568fbde5abc032e81c0
Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com>
This update modifies the boot data functional test to account for the
recently added redundancy where boot data entries are duplicated on
each page. It introduces `write_dup_boot_data` to simulate various
valid/invalid states using bitmaps and updates existing tests to
iterate through these scenarios.

Change-Id: I6767b3205759c1285c7e31e2802935cf1cf38ff9
Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com>
This change adds an `events` field to the `boot_log_t` structure to track
specific events during the boot process. Specifically, it introduces a
`kBootLogEventRedundancy` flag that indicates if the boot data redundancy
was fixed by the ROM_EXT.

The `events` field is populated in `rom_ext_start` based on the
`boot_data_validity` check. A new end-to-end test is added to verify that
the redundancy fix is correctly signaled on the first boot after a
bitstream load and not on subsequent resets.

Change-Id: I2a3417d4e588f916bdb1ca4127a2bf0e4917d8a1
Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com>
This change adds a call to `boot_data_check` after reading back boot
data. This ensures that the newly written entry is not only bit-for-bit
correct but also indeed valid according to the boot data integrity rules.

Change-Id: Idde3c0af5ed5478c1bd94e3a76a43ae9c016a537
Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com>
This change ignores the result of the boot data write operation to
avoid falling into a boot loop if the redundancy fix fails.

Change-Id: Id46734c58c36024249775b0b4e61114a6de26344
Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com>
Copy link
Contributor

@siemen11 siemen11 left a comment

Choose a reason for hiding this comment

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

Thank you for the offline discussions, change looks good to me!

@timothytrippel timothytrippel merged commit f35f93c into lowRISC:earlgrey_1.0.0 Jan 22, 2026
65 of 66 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.

4 participants