Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rom_ext] Ownership transfer manual cherry-picks from earlgrey_es_sival #24939

Merged
merged 4 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions quality/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ RUST_TARGETS = [
"//sw/host/tests/chip/gpio:gpio",
"//sw/host/tests/chip/power_virus:power_virus",
"//sw/host/tests/chip/spi_device:spi_passthru",
"//sw/host/tests/ownership:rescue_limit_test",
"//sw/host/tests/ownership:rescue_permission_test",
"//sw/host/tests/ownership:transfer_lib",
"//sw/host/tests/ownership:transfer_test",
"//sw/host/tests/rom/e2e_bootstrap_disabled:e2e_bootstrap_disabled",
Expand Down
14 changes: 11 additions & 3 deletions sw/device/silicon_creator/lib/drivers/flash_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,8 @@ static void flash_ctrl_mp_region_cfg_reset(flash_ctrl_region_index_t region) {
static void flash_ctrl_mp_region_cfg_write(flash_ctrl_region_index_t region,
flash_ctrl_cfg_t cfg,
flash_ctrl_perms_t perms,
multi_bit_bool_t en) {
multi_bit_bool_t en,
hardened_bool_t lock) {
#define FLASH_CTRL_MP_REGION_CFG_WRITE_(region_macro_arg) \
case ((region_macro_arg)): { \
HARDENED_CHECK_EQ(region, (region_macro_arg)); \
Expand Down Expand Up @@ -624,6 +625,12 @@ static void flash_ctrl_mp_region_cfg_write(flash_ctrl_region_index_t region,
sec_mmio_write32( \
kBase + FLASH_CTRL_MP_REGION_CFG_##region_macro_arg##_REG_OFFSET, \
mp_region_cfg); \
if (lock != kHardenedBoolFalse) { \
sec_mmio_write32( \
kBase + \
FLASH_CTRL_REGION_CFG_REGWEN_##region_macro_arg##_REG_OFFSET, \
0); \
} \
return; \
}

Expand All @@ -639,7 +646,8 @@ static void flash_ctrl_mp_region_cfg_write(flash_ctrl_region_index_t region,
void flash_ctrl_data_region_protect(flash_ctrl_region_index_t region,
uint32_t page_offset, uint32_t num_pages,
flash_ctrl_perms_t perms,
flash_ctrl_cfg_t cfg) {
flash_ctrl_cfg_t cfg,
hardened_bool_t lock) {
// Reset the region's configuration via the MP_REGION_CFG_${region} register.
// This temporarily disables memory protection for the region.
flash_ctrl_mp_region_cfg_reset(region);
Expand All @@ -649,7 +657,7 @@ void flash_ctrl_data_region_protect(flash_ctrl_region_index_t region,

// Write the new value of MP_REGION_CFG_${region}.
flash_ctrl_mp_region_cfg_write(region, cfg, perms,
/*en=*/kMultiBitBool4True);
/*en=*/kMultiBitBool4True, lock);
}

void flash_ctrl_info_cfg_set(const flash_ctrl_info_page_t *info_page,
Expand Down
3 changes: 2 additions & 1 deletion sw/device/silicon_creator/lib/drivers/flash_ctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,11 +529,12 @@ typedef uint32_t flash_ctrl_region_index_t;
* @param perms The read/write/erase permissions for this region.
* @param cfg Flash config values that are used to fill in some fields of the
* `MP_REGION_CFG_${region}` register.
* @param lock Lock the configuration for this region.
*/
void flash_ctrl_data_region_protect(flash_ctrl_region_index_t region,
uint32_t page_offset, uint32_t num_pages,
flash_ctrl_perms_t perms,
flash_ctrl_cfg_t cfg);
flash_ctrl_cfg_t cfg, hardened_bool_t lock);

/**
* Sets configuration settings for an info page.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,8 @@ TEST_P(DataRegionProtectTestSuite, ProtectRegionReadWriteEraseEnabled) {
.scrambling = BoolToMultiBitBool4(kFlashScrambling),
.ecc = BoolToMultiBitBool4(kFlashEcc),
.he = BoolToMultiBitBool4(kFlashHe),
});
},
kHardenedBoolFalse);
}

} // namespace
Expand Down
5 changes: 3 additions & 2 deletions sw/device/silicon_creator/lib/drivers/mock_flash_ctrl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,10 @@ void flash_ctrl_info_cfg_set(const flash_ctrl_info_page_t *info_page,
void flash_ctrl_data_region_protect(flash_ctrl_region_index_t region,
uint32_t page_offset, uint32_t num_pages,
flash_ctrl_perms_t perms,
flash_ctrl_cfg_t cfg) {
flash_ctrl_cfg_t cfg,
hardened_bool_t lock) {
MockFlashCtrl::Instance().DataRegionProtect(region, page_offset, num_pages,
perms, cfg);
perms, cfg, lock);
}

void flash_ctrl_bank_erase_perms_set(hardened_bool_t enable) {
Expand Down
2 changes: 1 addition & 1 deletion sw/device/silicon_creator/lib/drivers/mock_flash_ctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class MockFlashCtrl : public global_mock::GlobalMock<MockFlashCtrl> {
MOCK_METHOD(void, DataRegionProtect,
(flash_ctrl_region_index_t region, uint32_t page_offset,
uint32_t num_pages, flash_ctrl_perms_t perms,
flash_ctrl_cfg_t cfg));
flash_ctrl_cfg_t cfg, hardened_bool_t));
MOCK_METHOD(void, InfoCfgSet,
(const flash_ctrl_info_page_t *, flash_ctrl_cfg_t));
MOCK_METHOD(void, BankErasePermsSet, (hardened_bool_t));
Expand Down
27 changes: 19 additions & 8 deletions sw/device/silicon_creator/lib/ownership/owner_block.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ rom_error_t owner_block_parse(const owner_block_t *block,
}

rom_error_t owner_block_flash_apply(const owner_flash_config_t *flash,
uint32_t config_side,
uint32_t primary_side) {
uint32_t config_side, uint32_t lockdown) {
if ((hardened_bool_t)flash == kHardenedBoolFalse)
return kErrorOk;
// TODO: Hardening: lockdown should be one of kBootSlotA, kBootSlotB or
// kHardenedBoolFalse.
uint32_t start = config_side == kBootSlotA ? 0
: config_side == kBootSlotB ? kFlashBankSize
: 0xFFFFFFFF;
Expand Down Expand Up @@ -118,13 +119,23 @@ rom_error_t owner_block_flash_apply(const owner_flash_config_t *flash,
.erase = bitfield_field32_read(val, FLASH_CONFIG_ERASE),
};

if (config_side == primary_side &&
bitfield_field32_read(val, FLASH_CONFIG_PROTECT_WHEN_PRIMARY) !=
kMultiBitBool4False) {
perm.write = kMultiBitBool4False;
perm.erase = kMultiBitBool4False;
if (lockdown == config_side) {
if (bitfield_field32_read(val, FLASH_CONFIG_PROTECT_WHEN_PRIMARY) !=
kMultiBitBool4False) {
perm.write = kMultiBitBool4False;
perm.erase = kMultiBitBool4False;
}
}

hardened_bool_t lock = kHardenedBoolFalse;
if (lockdown != kHardenedBoolFalse) {
if (bitfield_field32_read(val, FLASH_CONFIG_LOCK) !=
kMultiBitBool4False) {
lock = kHardenedBoolTrue;
}
}
flash_ctrl_data_region_protect(i, config->start, config->size, perm, cfg);
flash_ctrl_data_region_protect(i, config->start, config->size, perm, cfg,
lock);
}
}
return kErrorOk;
Expand Down
7 changes: 4 additions & 3 deletions sw/device/silicon_creator/lib/ownership/owner_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,13 @@ rom_error_t owner_block_parse(const owner_block_t *block,
*
* @param flash A pointer to a flash configuration struct.
* @param config_side Which side of the flash to configure.
* @param primary_side Which side of the flash is primary.
* @param lockdown Apply any special lockdown configuration to the specified
* side of the flash. May use kHardenedBoolFalse to skip
* lockdown.
* @return error code.
*/
rom_error_t owner_block_flash_apply(const owner_flash_config_t *flash,
uint32_t config_side,
uint32_t primary_side);
uint32_t config_side, uint32_t lockdown);

/**
* Apply the flash info configuration parameters from the owner block.
Expand Down
51 changes: 30 additions & 21 deletions sw/device/silicon_creator/lib/ownership/owner_block_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -239,21 +239,24 @@ TEST_F(OwnerBlockTest, FlashConfigApplySideA) {
FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4True),
FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
kMultiBitBool4False)));
kMultiBitBool4False),
kHardenedBoolFalse));
EXPECT_CALL(
flash_ctrl_,
DataRegionProtect(1, 32, 192,
FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4True),
FlashCfg(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4False)));
DataRegionProtect(
1, 32, 192,
FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4True),
FlashCfg(kMultiBitBool4True, kMultiBitBool4True, kMultiBitBool4False),
kHardenedBoolFalse));
EXPECT_CALL(
flash_ctrl_,
DataRegionProtect(2, 224, 32,
FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4True),
FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
kMultiBitBool4True)));
kMultiBitBool4True),
kHardenedBoolFalse));

rom_error_t error =
owner_block_flash_apply(&simple_flash_config, kBootSlotA, 0);
Expand All @@ -270,21 +273,24 @@ TEST_F(OwnerBlockTest, FlashConfigApplySideAPrimary) {
FlashPerms(kMultiBitBool4True, kMultiBitBool4False,
kMultiBitBool4False),
FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
kMultiBitBool4False)));
kMultiBitBool4False),
kHardenedBoolFalse));
EXPECT_CALL(
flash_ctrl_,
DataRegionProtect(1, 32, 192,
FlashPerms(kMultiBitBool4True, kMultiBitBool4False,
kMultiBitBool4False),
FlashCfg(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4False)));
DataRegionProtect(
1, 32, 192,
FlashPerms(kMultiBitBool4True, kMultiBitBool4False,
kMultiBitBool4False),
FlashCfg(kMultiBitBool4True, kMultiBitBool4True, kMultiBitBool4False),
kHardenedBoolFalse));
EXPECT_CALL(
flash_ctrl_,
DataRegionProtect(2, 224, 32,
FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4True),
FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
kMultiBitBool4True)));
kMultiBitBool4True),
kHardenedBoolFalse));

rom_error_t error =
owner_block_flash_apply(&simple_flash_config, kBootSlotA, kBootSlotA);
Expand All @@ -299,21 +305,24 @@ TEST_F(OwnerBlockTest, FlashConfigApplySideB) {
FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4True),
FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
kMultiBitBool4False)));
kMultiBitBool4False),
kHardenedBoolFalse));
EXPECT_CALL(
flash_ctrl_,
DataRegionProtect(4, 256 + 32, 192,
FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4True),
FlashCfg(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4False)));
DataRegionProtect(
4, 256 + 32, 192,
FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4True),
FlashCfg(kMultiBitBool4True, kMultiBitBool4True, kMultiBitBool4False),
kHardenedBoolFalse));
EXPECT_CALL(
flash_ctrl_,
DataRegionProtect(5, 256 + 224, 32,
FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
kMultiBitBool4True),
FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
kMultiBitBool4True)));
kMultiBitBool4True),
kHardenedBoolFalse));

rom_error_t error =
owner_block_flash_apply(&simple_flash_config, kBootSlotB, 0);
Expand Down
35 changes: 27 additions & 8 deletions sw/device/silicon_creator/lib/ownership/ownership.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,12 @@ static rom_error_t locked_owner_init(boot_data_t *bootdata,
return kErrorOwnershipBadInfoPage;
}
HARDENED_RETURN_IF_ERROR(owner_block_parse(&owner_page[0], config, keyring));
HARDENED_RETURN_IF_ERROR(owner_block_flash_apply(config->flash, kBootSlotA,
bootdata->primary_bl0_slot));
HARDENED_RETURN_IF_ERROR(owner_block_flash_apply(config->flash, kBootSlotB,
bootdata->primary_bl0_slot));
HARDENED_RETURN_IF_ERROR(
owner_block_flash_apply(config->flash, kBootSlotA,
/*lockdown=*/kHardenedBoolFalse));
HARDENED_RETURN_IF_ERROR(
owner_block_flash_apply(config->flash, kBootSlotB,
/*lockdown=*/kHardenedBoolFalse));
HARDENED_RETURN_IF_ERROR(owner_block_info_apply(config->info));
return kErrorOk;
}
Expand Down Expand Up @@ -150,8 +152,9 @@ static rom_error_t unlocked_init(boot_data_t *bootdata, owner_config_t *config,
// Configure the primary half of the flash as Owner Page 0 requests.
HARDENED_RETURN_IF_ERROR(
owner_block_parse(&owner_page[0], config, keyring));
HARDENED_RETURN_IF_ERROR(owner_block_flash_apply(
config->flash, bootdata->primary_bl0_slot, bootdata->primary_bl0_slot));
HARDENED_RETURN_IF_ERROR(
owner_block_flash_apply(config->flash, bootdata->primary_bl0_slot,
/*lockdown=*/kHardenedBoolFalse));
}

if (ownership_page1_valid_for_transfer(bootdata) == kHardenedBoolTrue) {
Expand All @@ -160,8 +163,9 @@ static rom_error_t unlocked_init(boot_data_t *bootdata, owner_config_t *config,
HARDENED_RETURN_IF_ERROR(
owner_block_parse(&owner_page[1], config, keyring));
}
HARDENED_RETURN_IF_ERROR(owner_block_flash_apply(config->flash, secondary,
bootdata->primary_bl0_slot));
HARDENED_RETURN_IF_ERROR(
owner_block_flash_apply(config->flash, secondary,
/*lockdown=*/kHardenedBoolFalse));
HARDENED_RETURN_IF_ERROR(owner_block_info_apply(config->info));
return kErrorOk;
}
Expand Down Expand Up @@ -244,6 +248,21 @@ rom_error_t ownership_init(boot_data_t *bootdata, owner_config_t *config,
return error;
}

rom_error_t ownership_flash_lockdown(boot_data_t *bootdata,
const owner_config_t *config) {
if (bootdata->ownership_state == kOwnershipStateLockedOwner) {
HARDENED_RETURN_IF_ERROR(
owner_block_flash_apply(config->flash, kBootSlotA,
/*lockdown=*/bootdata->primary_bl0_slot));
HARDENED_RETURN_IF_ERROR(
owner_block_flash_apply(config->flash, kBootSlotB,
/*lockdown=*/bootdata->primary_bl0_slot));
} else {
HARDENED_CHECK_NE(bootdata->ownership_state, kOwnershipStateLockedOwner);
}
return kErrorOk;
}

void ownership_page_seal(size_t page) {
size_t seal_len = (uintptr_t)&owner_page[0].seal - (uintptr_t)&owner_page[0];
hmac_digest_t digest;
Expand Down
11 changes: 11 additions & 0 deletions sw/device/silicon_creator/lib/ownership/ownership.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ rom_error_t ownership_init(boot_data_t *bootdata, owner_config_t *config,
*/
hardened_bool_t ownership_page1_valid_for_transfer(boot_data_t *bootdata);

/**
* Lockdown the flash configuration.
*
*
* @param bootdata The current bootdata.
* @param config The current owner configuration.
* @return error state.
*/
rom_error_t ownership_flash_lockdown(boot_data_t *bootdata,
const owner_config_t *config);

/**
* Seal an owner page.
*
Expand Down
Loading
Loading