[sw/silicon_creator] Randomize the start of OTBN write loops
Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/lib/drivers/BUILD b/sw/device/silicon_creator/lib/drivers/BUILD
index 9466c50..cb0ea9c 100644
--- a/sw/device/silicon_creator/lib/drivers/BUILD
+++ b/sw/device/silicon_creator/lib/drivers/BUILD
@@ -282,6 +282,7 @@
"//sw/device/lib/base:abs_mmio",
"//sw/device/lib/base:bitfield",
"//sw/device/silicon_creator/lib:error",
+ "//sw/device/silicon_creator/lib/drivers:rnd",
],
)
diff --git a/sw/device/silicon_creator/lib/drivers/meson.build b/sw/device/silicon_creator/lib/drivers/meson.build
index bd3bc39..791aefe 100644
--- a/sw/device/silicon_creator/lib/drivers/meson.build
+++ b/sw/device/silicon_creator/lib/drivers/meson.build
@@ -499,6 +499,7 @@
],
dependencies: [
sw_lib_abs_mmio,
+ sw_silicon_creator_lib_driver_rnd,
],
),
)
diff --git a/sw/device/silicon_creator/lib/drivers/otbn.c b/sw/device/silicon_creator/lib/drivers/otbn.c
index d944c9c..90a578d 100644
--- a/sw/device/silicon_creator/lib/drivers/otbn.c
+++ b/sw/device/silicon_creator/lib/drivers/otbn.c
@@ -10,6 +10,7 @@
#include "sw/device/lib/base/abs_mmio.h"
#include "sw/device/lib/base/bitfield.h"
+#include "sw/device/silicon_creator/lib/drivers/rnd.h"
#include "sw/device/silicon_creator/lib/error.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
@@ -57,6 +58,30 @@
return kErrorOk;
}
+/**
+ * Helper function for writing to OTBN's DMEM or IMEM.
+ *
+ * @param dest_addr Destination address.
+ * @param src Source buffer.
+ * @param num_words Number of words to copy.
+ */
+static void otbn_write(uint32_t dest_addr, const uint32_t *src,
+ size_t num_words) {
+ // Start from a random index less than `num_words`.
+ size_t i = ((uint64_t)rnd_uint32() * (uint64_t)num_words) >> 32;
+ enum { kStep = 1 };
+ size_t iter_cnt = 0;
+ for (; launder32(iter_cnt) < num_words; ++iter_cnt) {
+ abs_mmio_write32(dest_addr + i * sizeof(uint32_t), src[i]);
+ i += kStep;
+ if (launder32(i) >= num_words) {
+ i -= num_words;
+ }
+ HARDENED_CHECK_LT(i, num_words);
+ }
+ HARDENED_CHECK_EQ(iter_cnt, num_words);
+}
+
void otbn_execute(void) {
abs_mmio_write32(kBase + OTBN_CMD_REG_OFFSET, kOtbnCmdExecute);
}
@@ -74,15 +99,7 @@
size_t num_words) {
RETURN_IF_ERROR(
check_offset_len(offset_bytes, num_words, kOtbnIMemSizeBytes));
-
- size_t i = 0;
- for (; launder32(i) < num_words; ++i) {
- abs_mmio_write32(
- kBase + OTBN_IMEM_REG_OFFSET + offset_bytes + i * sizeof(uint32_t),
- src[i]);
- }
- HARDENED_CHECK_EQ(i, num_words);
-
+ otbn_write(kBase + OTBN_IMEM_REG_OFFSET + offset_bytes, src, num_words);
return kErrorOk;
}
@@ -90,15 +107,7 @@
size_t num_words) {
RETURN_IF_ERROR(
check_offset_len(offset_bytes, num_words, kOtbnDMemSizeBytes));
-
- size_t i = 0;
- for (; launder32(i) < num_words; ++i) {
- abs_mmio_write32(
- kBase + OTBN_DMEM_REG_OFFSET + offset_bytes + i * sizeof(uint32_t),
- src[i]);
- }
- HARDENED_CHECK_EQ(i, num_words);
-
+ otbn_write(kBase + OTBN_DMEM_REG_OFFSET + offset_bytes, src, num_words);
return kErrorOk;
}
diff --git a/sw/device/silicon_creator/lib/drivers/otbn_unittest.cc b/sw/device/silicon_creator/lib/drivers/otbn_unittest.cc
index 60af1a0..25ce156 100644
--- a/sw/device/silicon_creator/lib/drivers/otbn_unittest.cc
+++ b/sw/device/silicon_creator/lib/drivers/otbn_unittest.cc
@@ -8,6 +8,7 @@
#include "gtest/gtest.h"
#include "sw/device/lib/base/testing/mock_abs_mmio.h"
+#include "sw/device/silicon_creator/lib/drivers/mock_rnd.h"
#include "sw/device/silicon_creator/testing/mask_rom_test.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
@@ -16,11 +17,13 @@
namespace otbn_unittest {
namespace {
using ::testing::ElementsAre;
+using ::testing::Return;
class OtbnTest : public mask_rom_test::MaskRomTest {
protected:
uint32_t base_ = TOP_EARLGREY_OTBN_BASE_ADDR;
mask_rom_test::MockAbsMmio mmio_;
+ mask_rom_test::MockRnd rnd_;
};
class StartTest : public OtbnTest {};
@@ -76,6 +79,7 @@
std::array<uint32_t, 2> test_data = {0x12345678, 0xabcdef01};
+ EXPECT_CALL(rnd_, Uint32()).WillOnce(Return(0));
EXPECT_ABS_WRITE32(base_ + OTBN_IMEM_REG_OFFSET, test_data[0]);
EXPECT_ABS_WRITE32(base_ + OTBN_IMEM_REG_OFFSET + 4, test_data[1]);
@@ -88,6 +92,7 @@
std::array<uint32_t, 2> test_data = {0x12345678, 0xabcdef01};
+ EXPECT_CALL(rnd_, Uint32()).WillOnce(Return(0));
EXPECT_ABS_WRITE32(base_ + OTBN_IMEM_REG_OFFSET + 4, test_data[0]);
EXPECT_ABS_WRITE32(base_ + OTBN_IMEM_REG_OFFSET + 8, test_data[1]);
@@ -102,6 +107,7 @@
std::array<uint32_t, 2> test_data = {0x12345678, 0xabcdef01};
+ EXPECT_CALL(rnd_, Uint32()).WillOnce(Return(0));
EXPECT_ABS_WRITE32(base_ + OTBN_DMEM_REG_OFFSET, test_data[0]);
EXPECT_ABS_WRITE32(base_ + OTBN_DMEM_REG_OFFSET + 4, test_data[1]);
@@ -114,6 +120,7 @@
std::array<uint32_t, 2> test_data = {0x12345678, 0xabcdef01};
+ EXPECT_CALL(rnd_, Uint32()).WillOnce(Return(0));
EXPECT_ABS_WRITE32(base_ + OTBN_DMEM_REG_OFFSET + 4, test_data[0]);
EXPECT_ABS_WRITE32(base_ + OTBN_DMEM_REG_OFFSET + 8, test_data[1]);