Skip to content

Commit

Permalink
[sw/rom] Add rom_ext sec_mmio initialization
Browse files Browse the repository at this point in the history
sec_mmio initialization for the ROM_EXT clears the current check count
expectation and resets all entries in the expectation table that were
not used by the ROM. This is to ensure that an attacker is not able to
recreate the state of the expectation table after injecting a reset
fault.

Signed-off-by: Miguel Osorio <miguelosorio@google.com>
  • Loading branch information
moidx committed Oct 21, 2021
1 parent b8ddad8 commit ddea231
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
11 changes: 11 additions & 0 deletions sw/device/silicon_creator/lib/base/sec_mmio.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ void sec_mmio_init(sec_mmio_shutdown_handler cb) {
sec_mmio_ctx.expected_write_count = 0;
for (size_t i = 0; i < ARRAYSIZE(sec_mmio_ctx.addrs); ++i) {
sec_mmio_ctx.addrs[i] = UINT32_MAX;
sec_mmio_ctx.values[i] = UINT32_MAX;
}
}

void sec_mmio_next_stage_init(sec_mmio_shutdown_handler cb) {
sec_mmio_shutdown_cb = cb;
sec_mmio_ctx.check_count = 0;
for (size_t i = sec_mmio_ctx.last_index; i < ARRAYSIZE(sec_mmio_ctx.addrs);
++i) {
sec_mmio_ctx.addrs[i] = UINT32_MAX;
sec_mmio_ctx.values[i] = UINT32_MAX;
}
}

Expand Down
15 changes: 15 additions & 0 deletions sw/device/silicon_creator/lib/base/sec_mmio.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,21 @@ typedef void (*sec_mmio_shutdown_handler)(rom_error_t);
*/
void sec_mmio_init(sec_mmio_shutdown_handler cb);

/**
* Executes sec_mmio next boot stage initialization.
*
* Registers the `cb` callback handler, and performs the following operations to
* the internal `sec_mmio_ctx_t` context:
*
* - Clear the check count. This allows the caller to reset the
* `sec_mmio_check_counters()` expected count argument.
* - Reset all expected address and values in the expectations table starting at
* the last_index.
*
* @param cb Shutdown module callback handler.
*/
void sec_mmio_next_stage_init(sec_mmio_shutdown_handler cb);

/**
* Reads an aligned uint32_t from the MMIO region `addr`.
*
Expand Down
41 changes: 41 additions & 0 deletions sw/device/silicon_creator/lib/base/sec_mmio_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extern sec_mmio_ctx_t sec_mmio_ctx;
namespace sec_mmio_unittest {
namespace {
using ::testing::Each;
using ::testing::ElementsAreArray;
using ::testing::Eq;
using ::testing::Test;

Expand All @@ -46,6 +47,46 @@ TEST_F(SecMmioTest, Initialize) {
EXPECT_EQ(ctx_->last_index, 0);
EXPECT_EQ(ctx_->write_count, 0);
EXPECT_THAT(ctx_->addrs, Each(Eq(UINT32_MAX)));
EXPECT_THAT(ctx_->values, Each(Eq(UINT32_MAX)));
}

TEST_F(SecMmioTest, NextStageInitialize) {
// Ensure the register file size is greater than zero to ensure checks are
// performed on non-zero sized arrays.
static_assert(kSecMmioRegFileSize > 2);
std::array<uint32_t, kSecMmioRegFileSize> expected_addrs;
std::array<uint32_t, kSecMmioRegFileSize> expected_values;

// Prefill data to simulate a pre-initialization conditions. Use different
// values for `addr` and `values` to ensure the test checks are specific for
// each array.
for (size_t i = 0; i < kSecMmioRegFileSize; ++i) {
ctx_->addrs[i] = i ^ 0xa;
ctx_->values[i] = i ^ 0x5;
expected_addrs[i] = ctx_->addrs[i];
expected_values[i] = ctx_->values[i];
}

ctx_->check_count = 5;
ctx_->expected_write_count = 6;
ctx_->write_count = 6;

const uint32_t kExpectedWriteCount = kSecMmioRegFileSize / 2;
ctx_->last_index = kExpectedWriteCount;

for (size_t i = kExpectedWriteCount; i < kSecMmioRegFileSize; ++i) {
expected_addrs[i] = UINT32_MAX;
expected_values[i] = UINT32_MAX;
}

sec_mmio_next_stage_init(+[](rom_error_t) { std::abort(); });

EXPECT_EQ(ctx_->write_count, 6);
EXPECT_EQ(ctx_->expected_write_count, 6);
EXPECT_EQ(ctx_->last_index, kExpectedWriteCount);
EXPECT_EQ(ctx_->check_count, 0);
EXPECT_THAT(ctx_->addrs, ElementsAreArray(expected_addrs));
EXPECT_THAT(ctx_->values, ElementsAreArray(expected_values));
}

TEST_F(SecMmioTest, Read32OrDie) {
Expand Down

0 comments on commit ddea231

Please sign in to comment.