5 #include "sw/device/silicon_creator/lib/drivers/otbn.h"
10 #include "gtest/gtest.h"
11 #include "sw/device/lib/base/mock_abs_mmio.h"
12 #include "sw/device/silicon_creator/lib/base/mock_sec_mmio.h"
13 #include "sw/device/silicon_creator/lib/drivers/mock_rnd.h"
14 #include "sw/device/silicon_creator/testing/rom_test.h"
17 #include "otbn_regs.h"
19 namespace otbn_unittest {
21 using ::testing::ElementsAre;
22 using ::testing::Return;
35 EXPECT_ABS_WRITE32(base_ + OTBN_INTR_STATE_REG_OFFSET,
37 {OTBN_INTR_COMMON_DONE_BIT, 1},
39 EXPECT_ABS_WRITE32(base_ + OTBN_CMD_REG_OFFSET, cmd);
41 EXPECT_ABS_READ32(base_ + OTBN_INTR_STATE_REG_OFFSET, 0);
42 EXPECT_ABS_READ32(base_ + OTBN_INTR_STATE_REG_OFFSET,
44 {OTBN_INTR_COMMON_DONE_BIT, 1},
46 EXPECT_ABS_WRITE32(base_ + OTBN_INTR_STATE_REG_OFFSET,
48 {OTBN_INTR_COMMON_DONE_BIT, 1},
51 EXPECT_ABS_READ32(base_ + OTBN_ERR_BITS_REG_OFFSET, err_bits);
52 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET,
status);
54 if (err_bits == err_bits_ok_ &&
status == kScOtbnStatusIdle) {
55 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET,
status);
60 uint32_t err_bits_ok_ = 0;
61 rom_test::MockAbsMmio abs_mmio_;
62 rom_test::MockRnd rnd_;
63 rom_test::MockSecMmio sec_mmio_;
70 static_assert(OTBN_IMEM_SIZE_BYTES >= 8,
"OTBN IMEM size too small.");
73 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
74 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
76 EXPECT_SEC_WRITE32(base_ + OTBN_CTRL_REG_OFFSET, 0x1);
78 ExpectCmdRun(kScOtbnCmdExecute, err_bits_ok_, kScOtbnStatusIdle);
80 EXPECT_EQ(sc_otbn_execute(), kErrorOk);
83 TEST_F(ExecuteTest, ExecuteError) {
85 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
86 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
88 EXPECT_SEC_WRITE32(base_ + OTBN_CTRL_REG_OFFSET, 0x1);
91 ExpectCmdRun(kScOtbnCmdExecute, 1 << OTBN_ERR_BITS_FATAL_SOFTWARE_BIT,
94 EXPECT_EQ(sc_otbn_execute(), kErrorOtbnExecutionFailed);
97 TEST_F(ExecuteTest, ExecuteBusy) {
99 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
100 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
102 EXPECT_SEC_WRITE32(base_ + OTBN_CTRL_REG_OFFSET, 0x01);
105 ExpectCmdRun(kScOtbnCmdExecute, err_bits_ok_, kScOtbnStatusBusyExecute);
107 EXPECT_EQ(sc_otbn_execute(), kErrorOtbnExecutionFailed);
110 TEST_F(ExecuteTest, ExecuteBlockUntilIdle) {
112 static_assert(OTBN_IMEM_SIZE_BYTES >= 8,
"OTBN IMEM size too small.");
114 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET,
115 kScOtbnStatusBusySecWipeDmem);
116 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET,
117 kScOtbnStatusBusySecWipeDmem);
118 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET,
119 kScOtbnStatusBusySecWipeDmem);
122 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
123 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
125 EXPECT_SEC_WRITE32(base_ + OTBN_CTRL_REG_OFFSET, 0x1);
127 ExpectCmdRun(kScOtbnCmdExecute, err_bits_ok_, kScOtbnStatusIdle);
129 EXPECT_EQ(sc_otbn_execute(), kErrorOk);
135 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusBusyExecute);
136 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusBusyExecute);
137 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusBusyExecute);
138 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusBusyExecute);
139 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
140 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
142 EXPECT_EQ(sc_otbn_busy_wait_for_done(), kErrorOk);
148 ExpectCmdRun(kScOtbnCmdSecWipeImem, err_bits_ok_, kScOtbnStatusIdle);
150 EXPECT_EQ(sc_otbn_imem_sec_wipe(), kErrorOk);
153 TEST_F(ImemSecWipeTest, Failure) {
154 ExpectCmdRun(kScOtbnCmdSecWipeImem, 1 << OTBN_ERR_BITS_FATAL_SOFTWARE_BIT,
157 EXPECT_EQ(sc_otbn_imem_sec_wipe(), kErrorOtbnSecWipeImemFailed);
163 ExpectCmdRun(kScOtbnCmdSecWipeDmem, err_bits_ok_, kScOtbnStatusIdle);
165 EXPECT_EQ(sc_otbn_dmem_sec_wipe(), kErrorOk);
168 TEST_F(DmemSecWipeTest, Failure) {
169 ExpectCmdRun(kScOtbnCmdSecWipeDmem, 1 << OTBN_ERR_BITS_FATAL_SOFTWARE_BIT,
172 EXPECT_EQ(sc_otbn_dmem_sec_wipe(), kErrorOtbnSecWipeDmemFailed);
179 static_assert(OTBN_DMEM_SIZE_BYTES >= 8,
"OTBN DMEM size too small.");
181 std::array<uint32_t, 2> test_data = {0x12345678, 0xabcdef01};
182 sc_otbn_addr_t dest_addr = 0;
184 EXPECT_CALL(rnd_, Uint32()).WillOnce(Return(0));
185 EXPECT_ABS_WRITE32(base_ + OTBN_DMEM_REG_OFFSET + dest_addr, test_data[0]);
186 EXPECT_ABS_WRITE32(base_ + OTBN_DMEM_REG_OFFSET + dest_addr + 4,
189 EXPECT_EQ(sc_otbn_dmem_write(2, test_data.data(), dest_addr), kErrorOk);
192 TEST_F(DmemWriteTest, SuccessWithOffset) {
194 static_assert(OTBN_DMEM_SIZE_BYTES >= 12,
"OTBN DMEM size too small.");
196 std::array<uint32_t, 2> test_data = {0x12345678, 0xabcdef01};
197 sc_otbn_addr_t dest_addr = 4;
199 EXPECT_CALL(rnd_, Uint32()).WillOnce(Return(0));
200 EXPECT_ABS_WRITE32(base_ + OTBN_DMEM_REG_OFFSET + dest_addr, test_data[0]);
201 EXPECT_ABS_WRITE32(base_ + OTBN_DMEM_REG_OFFSET + dest_addr + 4,
204 EXPECT_EQ(sc_otbn_dmem_write(2, test_data.data(), dest_addr), kErrorOk);
207 TEST_F(DmemWriteTest, FailureOutOfRange) {
208 std::array<uint32_t, 2> test_data = {0x12345678, 0xabcdef01};
209 sc_otbn_addr_t dest_addr = OTBN_DMEM_SIZE_BYTES;
211 EXPECT_EQ(sc_otbn_dmem_write(2, test_data.data(), dest_addr),
212 kErrorOtbnBadOffsetLen);
215 TEST_F(DmemWriteTest, FailureOverflowNumWords) {
218 (std::numeric_limits<size_t>::max() /
sizeof(uint32_t)) + 1;
219 sc_otbn_addr_t dest_addr = 0;
221 EXPECT_EQ(sc_otbn_dmem_write(num_words, NULL, dest_addr),
222 kErrorOtbnBadOffsetLen);
225 TEST_F(DmemWriteTest, FailureOverflowOffset) {
227 std::array<uint32_t, 2> test_data = {0x12345678, 0xabcdef01};
228 sc_otbn_addr_t dest_addr = std::numeric_limits<uint32_t>::max();
230 EXPECT_EQ(sc_otbn_dmem_write(test_data.size(), test_data.data(), dest_addr),
231 kErrorOtbnBadOffsetLen);
238 ASSERT_GE(OTBN_DMEM_SIZE_BYTES, 8);
239 static_assert(OTBN_DMEM_SIZE_BYTES >= 8,
"OTBN DMEM size too small.");
241 EXPECT_ABS_READ32(base_ + OTBN_DMEM_REG_OFFSET, 0x12345678);
242 EXPECT_ABS_READ32(base_ + OTBN_DMEM_REG_OFFSET + 4, 0xabcdef01);
244 std::array<uint32_t, 2> test_data = {0};
246 sc_otbn_addr_t src_addr = 0;
247 EXPECT_EQ(sc_otbn_dmem_read(2, src_addr, test_data.data()), kErrorOk);
248 EXPECT_THAT(test_data, ElementsAre(0x12345678, 0xabcdef01));
251 TEST_F(DmemReadTest, SuccessWithOffset) {
253 static_assert(OTBN_DMEM_SIZE_BYTES >= 12,
"OTBN DMEM size too small.");
255 EXPECT_ABS_READ32(base_ + OTBN_DMEM_REG_OFFSET + 4, 0x12345678);
256 EXPECT_ABS_READ32(base_ + OTBN_DMEM_REG_OFFSET + 8, 0xabcdef01);
258 std::array<uint32_t, 2> test_data = {0};
260 sc_otbn_addr_t src_addr = 4;
261 EXPECT_EQ(sc_otbn_dmem_read(2, src_addr, test_data.data()), kErrorOk);
262 EXPECT_THAT(test_data, ElementsAre(0x12345678, 0xabcdef01));
268 std::array<uint32_t, 2> imem_data = {0x01234567, 0x89abcdef};
269 std::array<uint32_t, 2> dmem_data = {0x456789ab, 0xcdef0123};
270 sc_otbn_addr_t dmem_data_offset = 0x12;
273 .imem_end = imem_data.data() + imem_data.size(),
274 .dmem_data_start = dmem_data.data(),
275 .dmem_data_end = dmem_data.data() + imem_data.size(),
276 .dmem_data_start_addr = dmem_data_offset,
280 static_assert(OTBN_DMEM_SIZE_BYTES >=
sizeof(uint32_t) * dmem_data.size(),
281 "OTBN DMEM size too small");
282 static_assert(OTBN_IMEM_SIZE_BYTES >=
sizeof(uint32_t) * imem_data.size(),
283 "OTBN IMEM size too small");
287 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusBusyExecute);
288 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET,
289 kScOtbnStatusBusySecWipeDmem);
291 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
292 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
294 ExpectCmdRun(kScOtbnCmdSecWipeDmem, err_bits_ok_, kScOtbnStatusIdle);
296 ExpectCmdRun(kScOtbnCmdSecWipeImem, err_bits_ok_, kScOtbnStatusIdle);
298 EXPECT_CALL(rnd_, Uint32()).WillOnce(Return(0));
299 EXPECT_ABS_WRITE32(base_ + OTBN_IMEM_REG_OFFSET, imem_data[0]);
300 EXPECT_ABS_WRITE32(base_ + OTBN_IMEM_REG_OFFSET +
sizeof(uint32_t),
303 EXPECT_CALL(rnd_, Uint32()).WillOnce(Return(0));
304 EXPECT_ABS_WRITE32(base_ + OTBN_DMEM_REG_OFFSET + dmem_data_offset,
307 base_ + OTBN_DMEM_REG_OFFSET + dmem_data_offset +
sizeof(uint32_t),
310 EXPECT_EQ(sc_otbn_load_app(app), kErrorOk);
313 TEST_F(OtbnAppTest, OtbnLoadInvalidAppEmptyImem) {
315 std::array<uint32_t, 0> imem_data = {};
316 std::array<uint32_t, 2> dmem_data = {0x456789ab, 0xcdef0123};
317 sc_otbn_addr_t dmem_data_offset = 0x12;
320 .imem_end = imem_data.data() + imem_data.size(),
321 .dmem_data_start = dmem_data.data(),
322 .dmem_data_end = dmem_data.data() + dmem_data.size(),
323 .dmem_data_start_addr = dmem_data_offset,
327 static_assert(OTBN_DMEM_SIZE_BYTES >=
sizeof(uint32_t) * dmem_data.size(),
328 "OTBN DMEM size too small");
329 static_assert(OTBN_IMEM_SIZE_BYTES >=
sizeof(uint32_t) * imem_data.size(),
330 "OTBN IMEM size too small");
332 EXPECT_EQ(sc_otbn_load_app(app), kErrorOtbnInvalidArgument);
335 TEST_F(OtbnAppTest, OtbnLoadInvalidAppImemOutOfRange) {
337 std::array<uint32_t, (OTBN_IMEM_SIZE_BYTES /
sizeof(uint32_t)) + 1>
339 std::array<uint32_t, 2> dmem_data = {0x456789ab, 0xcdef0123};
340 sc_otbn_addr_t dmem_data_offset = 0x12;
343 .imem_end = imem_data.data() + imem_data.size(),
344 .dmem_data_start = dmem_data.data(),
345 .dmem_data_end = dmem_data.data() + dmem_data.size(),
346 .dmem_data_start_addr = dmem_data_offset,
350 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
351 EXPECT_ABS_READ32(base_ + OTBN_STATUS_REG_OFFSET, kScOtbnStatusIdle);
353 ExpectCmdRun(kScOtbnCmdSecWipeDmem, err_bits_ok_, kScOtbnStatusIdle);
355 ExpectCmdRun(kScOtbnCmdSecWipeImem, err_bits_ok_, kScOtbnStatusIdle);
357 EXPECT_EQ(sc_otbn_load_app(app), kErrorOtbnBadOffsetLen);
363 constexpr uint32_t kDestAddr = 6;
364 std::array<uint32_t, 2> test_data = {0x12345678, 0xabcdef01};
368 OTBN_DMEM_SIZE_BYTES >=
sizeof(uint32_t) * test_data.size() + kDestAddr,
369 "OTBN DMEM size too small.");
371 EXPECT_CALL(rnd_, Uint32()).WillOnce(Return(0));
372 EXPECT_ABS_WRITE32(base_ + OTBN_DMEM_REG_OFFSET + kDestAddr, test_data[0]);
374 base_ + OTBN_DMEM_REG_OFFSET + kDestAddr +
sizeof(uint32_t),
377 EXPECT_EQ(sc_otbn_dmem_write(2, test_data.data(), kDestAddr), kErrorOk);
383 constexpr uint32_t kSrcAddr = 6;
384 std::array<uint32_t, 2> test_data = {0};
388 OTBN_DMEM_SIZE_BYTES >=
sizeof(uint32_t) * test_data.size() + kSrcAddr,
389 "OTBN DMEM size too small.");
391 EXPECT_ABS_READ32(base_ + OTBN_DMEM_REG_OFFSET + kSrcAddr, 0x12345678);
392 EXPECT_ABS_READ32(base_ + OTBN_DMEM_REG_OFFSET + kSrcAddr +
sizeof(uint32_t),
395 EXPECT_EQ(sc_otbn_dmem_read(2, kSrcAddr, test_data.data()), kErrorOk);
396 EXPECT_THAT(test_data, ElementsAre(0x12345678, 0xabcdef01));