Skip to content

Commit 56da5a0

Browse files
committed
[sw] Harden the new boot_data_write
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>
1 parent b561ed4 commit 56da5a0

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

sw/device/silicon_creator/lib/boot_data.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,8 @@ rom_error_t boot_data_write(const boot_data_t *boot_data) {
657657
// Find the active page and the next counter.
658658
active_page_info_t active_page;
659659
boot_data_t last_entry;
660-
RETURN_IF_ERROR(boot_data_active_page_find(&active_page, &last_entry));
660+
HARDENED_RETURN_IF_ERROR(
661+
boot_data_active_page_find(&active_page, &last_entry));
661662
if (active_page.has_valid_entry == kHardenedBoolTrue) {
662663
// Counters are rounded to the next even value to ensure wraparound happens
663664
// on both pages.
@@ -667,15 +668,21 @@ rom_error_t boot_data_write(const boot_data_t *boot_data) {
667668
// Write to the inactive page first, and then active page.
668669
// If both pages are invalid, write the page0 first.
669670
int inactive_idx = active_page.page == kPages[0];
670-
671671
boot_data_digest_compute(&new_entry, &new_entry.digest);
672+
// NE also covers the NULL case when both pages are invalid.
673+
HARDENED_CHECK_NE(active_page.page, kPages[inactive_idx]);
672674
RETURN_IF_ERROR(boot_data_entry_write(kPages[inactive_idx], 0, &new_entry,
673675
/*erase=*/kHardenedBoolTrue));
676+
HARDENED_RETURN_IF_ERROR(boot_data_entry_write(
677+
kPages[inactive_idx], 1, &new_entry, /*erase=*/kHardenedBoolFalse));
674678

679+
inactive_idx = !inactive_idx;
675680
new_entry.counter += 1;
676681
boot_data_digest_compute(&new_entry, &new_entry.digest);
677-
return boot_data_entry_write(kPages[!inactive_idx], 0, &new_entry,
678-
/*erase=*/kHardenedBoolTrue);
682+
RETURN_IF_ERROR(boot_data_entry_write(kPages[inactive_idx], 0, &new_entry,
683+
/*erase=*/kHardenedBoolTrue));
684+
return boot_data_entry_write(kPages[inactive_idx], 1, &new_entry,
685+
/*erase=*/kHardenedBoolFalse);
679686
}
680687

681688
/**

sw/device/silicon_creator/lib/boot_data_functest.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,10 +354,14 @@ rom_error_t write_empty_test(void) {
354354
boot_data_t boot_data;
355355
read_boot_data(kPages[0], 0, &boot_data);
356356
RETURN_IF_ERROR(compare_boot_data(&kTestBootData, &boot_data));
357+
read_boot_data(kPages[0], 1, &boot_data);
358+
RETURN_IF_ERROR(compare_boot_data(&kTestBootData, &boot_data));
357359
LOG_INFO("Page 0 OK");
358360

359361
read_boot_data(kPages[1], 0, &boot_data);
360362
RETURN_IF_ERROR(compare_boot_data(&kTestBootDataDual, &boot_data));
363+
read_boot_data(kPages[1], 1, &boot_data);
364+
RETURN_IF_ERROR(compare_boot_data(&kTestBootDataDual, &boot_data));
361365
LOG_INFO("Page 1 OK");
362366

363367
RETURN_IF_ERROR(boot_data_read(kLcStateProd, &boot_data));

0 commit comments

Comments
 (0)