Software APIs
dif_otbn_unittest.cc
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
6 
7 #include "gtest/gtest.h"
9 #include "sw/device/lib/base/mock_mmio.h"
12 
13 #include "otbn_regs.h" // Generated.
14 
15 namespace dif_otbn_unittest {
16 namespace {
19 using testing::Each;
20 using testing::Eq;
21 using testing::Test;
22 
23 class OtbnTest : public Test, public MmioTest {
24  protected:
25  void ExpectDeviceReset() {
26  EXPECT_WRITE32(OTBN_INTR_ENABLE_REG_OFFSET, 0);
27  EXPECT_WRITE32(OTBN_INTR_STATE_REG_OFFSET,
28  std::numeric_limits<uint32_t>::max());
29  }
30 
31  dif_otbn_t dif_otbn_ = {.base_addr = dev().region()};
32 };
33 
34 class ResetTest : public OtbnTest {};
35 
36 TEST_F(ResetTest, NullArgs) { EXPECT_DIF_BADARG(dif_otbn_reset(nullptr)); }
37 
38 TEST_F(ResetTest, Default) {
39  ExpectDeviceReset();
40 
41  EXPECT_DIF_OK(dif_otbn_reset(&dif_otbn_));
42 }
43 
44 class WriteCmdTest : public OtbnTest {};
45 
46 TEST_F(WriteCmdTest, NullArgs) {
47  EXPECT_DIF_BADARG(dif_otbn_write_cmd(nullptr, kDifOtbnCmdExecute));
48 }
49 
50 TEST_F(WriteCmdTest, Success) {
51  // Set EXECUTE command.
52  EXPECT_WRITE32(OTBN_CMD_REG_OFFSET, kDifOtbnCmdExecute);
53 
54  EXPECT_DIF_OK(dif_otbn_write_cmd(&dif_otbn_, kDifOtbnCmdExecute));
55 }
56 
57 class GetStatusTest : public OtbnTest {};
58 
59 TEST_F(GetStatusTest, NullArgs) {
60  EXPECT_DIF_BADARG(dif_otbn_get_status(nullptr, nullptr));
61 
62  EXPECT_DIF_BADARG(dif_otbn_get_status(&dif_otbn_, nullptr));
63 
64  dif_otbn_status_t status = kDifOtbnStatusBusySecWipeDmem;
66  EXPECT_EQ(status, kDifOtbnStatusBusySecWipeDmem);
67 }
68 
69 TEST_F(GetStatusTest, Success) {
70  EXPECT_READ32(OTBN_STATUS_REG_OFFSET, kDifOtbnStatusBusyExecute);
71 
74  EXPECT_EQ(status, kDifOtbnStatusBusyExecute);
75 }
76 
77 class GetErrBitsTest : public OtbnTest {};
78 
79 TEST_F(GetErrBitsTest, NullArgs) {
80  EXPECT_DIF_BADARG(dif_otbn_get_err_bits(nullptr, nullptr));
81 
82  EXPECT_DIF_BADARG(dif_otbn_get_err_bits(&dif_otbn_, nullptr));
83 
85  EXPECT_DIF_BADARG(dif_otbn_get_err_bits(nullptr, &err_bits));
86  EXPECT_EQ(err_bits, kDifOtbnErrBitsBadDataAddr);
87 }
88 
89 TEST_F(GetErrBitsTest, Success) {
90  EXPECT_READ32(OTBN_ERR_BITS_REG_OFFSET,
92 
93  dif_otbn_err_bits_t err_bits;
94  EXPECT_DIF_OK(dif_otbn_get_err_bits(&dif_otbn_, &err_bits));
95  EXPECT_EQ(err_bits,
97 }
98 
99 class GetInsnCntTest : public OtbnTest {};
100 
101 TEST_F(GetInsnCntTest, NullArgs) {
102  EXPECT_DIF_BADARG(dif_otbn_get_insn_cnt(nullptr, nullptr));
103 
104  EXPECT_DIF_BADARG(dif_otbn_get_insn_cnt(&dif_otbn_, nullptr));
105 
106  uint32_t insn_cnt = 55;
107  EXPECT_DIF_BADARG(dif_otbn_get_insn_cnt(nullptr, &insn_cnt));
108  EXPECT_EQ(insn_cnt, 55);
109 }
110 
111 TEST_F(GetInsnCntTest, Success) {
112  EXPECT_READ32(OTBN_INSN_CNT_REG_OFFSET, 55);
113 
114  uint32_t insn_cnt;
115  EXPECT_DIF_OK(dif_otbn_get_insn_cnt(&dif_otbn_, &insn_cnt));
116  EXPECT_EQ(insn_cnt, 55);
117 }
118 
119 class ImemWriteTest : public OtbnTest {};
120 
121 TEST_F(ImemWriteTest, NullArgs) {
122  uint32_t test_data[] = {0};
123 
124  EXPECT_DIF_BADARG(dif_otbn_imem_write(nullptr, 0, nullptr, 4));
125 
126  EXPECT_DIF_BADARG(dif_otbn_imem_write(nullptr, 0, test_data, 4));
127 
128  EXPECT_DIF_BADARG(dif_otbn_imem_write(&dif_otbn_, 0, nullptr, 4));
129 }
130 
131 TEST_F(ImemWriteTest, BadLenBytes) {
132  uint32_t test_data[] = {0};
133 
134  // `len_bytes` must be a multiple of 4 bytes.
135  EXPECT_DIF_BADARG(dif_otbn_imem_write(&dif_otbn_, 0, test_data, 1));
136 
137  EXPECT_DIF_BADARG(dif_otbn_imem_write(&dif_otbn_, 0, test_data, 2));
138 }
139 
140 TEST_F(ImemWriteTest, BadOffset) {
141  uint32_t test_data[] = {0};
142 
143  // `offset` must be 32b-aligned.
144  EXPECT_DIF_BADARG(dif_otbn_imem_write(&dif_otbn_, 1, test_data, 4));
145 
146  EXPECT_DIF_BADARG(dif_otbn_imem_write(&dif_otbn_, 2, test_data, 4));
147 }
148 
149 TEST_F(ImemWriteTest, BadAddressBeyondMemorySize) {
150  uint32_t test_data[] = {0};
151 
153  dif_otbn_imem_write(&dif_otbn_, OTBN_IMEM_SIZE_BYTES, test_data, 4));
154 }
155 
156 TEST_F(ImemWriteTest, BadAddressIntegerOverflow) {
157  uint32_t test_data[4] = {0};
158 
159  EXPECT_DIF_BADARG(dif_otbn_imem_write(&dif_otbn_, 0xFFFFFFFC, test_data, 16));
160 }
161 
162 TEST_F(ImemWriteTest, SuccessWithoutOffset) {
163  // Test assumption.
164  ASSERT_GE(OTBN_IMEM_SIZE_BYTES, 8);
165 
166  uint32_t test_data[2] = {0x12345678, 0xabcdef01};
167 
168  EXPECT_WRITE32(OTBN_IMEM_REG_OFFSET, test_data[0]);
169  EXPECT_WRITE32(OTBN_IMEM_REG_OFFSET + 4, test_data[1]);
170 
171  EXPECT_DIF_OK(dif_otbn_imem_write(&dif_otbn_, 0, test_data, 8));
172 }
173 
174 TEST_F(ImemWriteTest, SuccessWithOffset) {
175  // Test assumption.
176  ASSERT_GE(OTBN_IMEM_SIZE_BYTES, 12);
177 
178  uint32_t test_data[2] = {0x12345678, 0xabcdef01};
179 
180  EXPECT_WRITE32(OTBN_IMEM_REG_OFFSET + 4, test_data[0]);
181  EXPECT_WRITE32(OTBN_IMEM_REG_OFFSET + 8, test_data[1]);
182 
183  EXPECT_DIF_OK(dif_otbn_imem_write(&dif_otbn_, 4, test_data, 8));
184 }
185 
186 class ImemReadTest : public OtbnTest {};
187 
188 TEST_F(ImemReadTest, NullArgs) {
189  uint32_t test_data[2] = {0x12345678, 0xabcdef01};
190 
191  EXPECT_DIF_BADARG(dif_otbn_imem_read(nullptr, 0, nullptr, sizeof(test_data)));
192 
194  dif_otbn_imem_read(nullptr, 0, test_data, sizeof(test_data)));
195 
197  dif_otbn_imem_read(&dif_otbn_, 0, nullptr, sizeof(test_data)));
198 
199  // No side effects are expected.
200  EXPECT_EQ(test_data[0], 0x12345678);
201  EXPECT_EQ(test_data[1], 0xabcdef01);
202 }
203 
204 TEST_F(ImemReadTest, BadLenBytes) {
205  uint32_t test_data[2] = {0};
206 
207  // `len_bytes` must be a multiple of 4 bytes.
208  EXPECT_DIF_BADARG(dif_otbn_imem_read(&dif_otbn_, 0, test_data, 1));
209 
210  EXPECT_DIF_BADARG(dif_otbn_imem_read(&dif_otbn_, 0, test_data, 2));
211 }
212 
213 TEST_F(ImemReadTest, BadOffset) {
214  uint32_t test_data[2] = {0};
215 
216  // `offset` must be 32b-aligned.
218  dif_otbn_imem_read(&dif_otbn_, 1, test_data, sizeof(test_data)));
219 
221  dif_otbn_imem_read(&dif_otbn_, 2, test_data, sizeof(test_data)));
222 }
223 
224 TEST_F(ImemReadTest, SuccessWithoutOffset) {
225  // Assumption in the test.
226  ASSERT_GE(OTBN_IMEM_SIZE_BYTES, 8);
227 
228  uint32_t test_data[2] = {0};
229 
230  EXPECT_READ32(OTBN_IMEM_REG_OFFSET, 0x12345678);
231  EXPECT_READ32(OTBN_IMEM_REG_OFFSET + 4, 0xabcdef01);
232 
233  EXPECT_DIF_OK(dif_otbn_imem_read(&dif_otbn_, 0, test_data, 8));
234  EXPECT_EQ(test_data[0], 0x12345678);
235  EXPECT_EQ(test_data[1], 0xabcdef01);
236 }
237 
238 TEST_F(ImemReadTest, SuccessWithOffset) {
239  // Assumption in the test.
240  ASSERT_GE(OTBN_IMEM_SIZE_BYTES, 12);
241 
242  uint32_t test_data[2] = {0};
243 
244  EXPECT_READ32(OTBN_IMEM_REG_OFFSET + 4, 0x12345678);
245  EXPECT_READ32(OTBN_IMEM_REG_OFFSET + 8, 0xabcdef01);
246 
247  EXPECT_DIF_OK(dif_otbn_imem_read(&dif_otbn_, 4, test_data, 8));
248  EXPECT_EQ(test_data[0], 0x12345678);
249  EXPECT_EQ(test_data[1], 0xabcdef01);
250 }
251 
252 class DmemWriteTest : public OtbnTest {};
253 
254 TEST_F(DmemWriteTest, NullArgs) {
255  uint32_t test_data[1] = {0};
256 
257  EXPECT_DIF_BADARG(dif_otbn_dmem_write(nullptr, 0, nullptr, 4));
258 
259  EXPECT_DIF_BADARG(dif_otbn_dmem_write(nullptr, 0, test_data, 4));
260 
261  EXPECT_DIF_BADARG(dif_otbn_dmem_write(&dif_otbn_, 0, nullptr, 4));
262 }
263 
264 TEST_F(DmemWriteTest, BadLenBytes) {
265  uint32_t test_data[1] = {0};
266 
267  // `len_bytes` must be a multiple of 4 bytes.
268  EXPECT_DIF_BADARG(dif_otbn_dmem_write(&dif_otbn_, 0, test_data, 1));
269 
270  EXPECT_DIF_BADARG(dif_otbn_dmem_write(&dif_otbn_, 0, test_data, 2));
271 }
272 
273 TEST_F(DmemWriteTest, BadOffset) {
274  uint32_t test_data[1] = {0};
275 
276  // `offset` must be 32b-aligned.
277  EXPECT_DIF_BADARG(dif_otbn_dmem_write(&dif_otbn_, 1, test_data, 4));
278 
279  EXPECT_DIF_BADARG(dif_otbn_dmem_write(&dif_otbn_, 2, test_data, 4));
280 }
281 
282 TEST_F(DmemWriteTest, SuccessWithoutOffset) {
283  // Test assumption.
284  ASSERT_GE(OTBN_DMEM_SIZE_BYTES, 8);
285 
286  uint32_t test_data[2] = {0x12345678, 0xabcdef01};
287 
288  EXPECT_WRITE32(OTBN_DMEM_REG_OFFSET, test_data[0]);
289  EXPECT_WRITE32(OTBN_DMEM_REG_OFFSET + 4, test_data[1]);
290 
291  EXPECT_DIF_OK(dif_otbn_dmem_write(&dif_otbn_, 0, test_data, 8));
292 }
293 
294 TEST_F(DmemWriteTest, SuccessWithOffset) {
295  // Test assumption.
296  ASSERT_GE(OTBN_DMEM_SIZE_BYTES, 12);
297 
298  uint32_t test_data[2] = {0x12345678, 0xabcdef01};
299 
300  EXPECT_WRITE32(OTBN_DMEM_REG_OFFSET + 4, test_data[0]);
301  EXPECT_WRITE32(OTBN_DMEM_REG_OFFSET + 8, test_data[1]);
302 
303  EXPECT_DIF_OK(dif_otbn_dmem_write(&dif_otbn_, 4, test_data, 8));
304 }
305 
306 class DmemReadTest : public OtbnTest {};
307 
308 TEST_F(DmemReadTest, NullArgs) {
309  uint32_t test_data[2] = {0x12345678, 0xabcdef01};
310 
311  EXPECT_DIF_BADARG(dif_otbn_dmem_read(nullptr, 0, nullptr, sizeof(test_data)));
312 
314  dif_otbn_dmem_read(nullptr, 0, test_data, sizeof(test_data)));
315 
317  dif_otbn_dmem_read(&dif_otbn_, 0, nullptr, sizeof(test_data)));
318 
319  // No side effects are expected.
320  EXPECT_EQ(test_data[0], 0x12345678);
321  EXPECT_EQ(test_data[1], 0xabcdef01);
322 }
323 
324 TEST_F(DmemReadTest, BadLenBytes) {
325  uint32_t test_data[2] = {0};
326 
327  // `len_bytes` must be a multiple of 4 bytes.
328  EXPECT_DIF_BADARG(dif_otbn_dmem_read(&dif_otbn_, 0, test_data, 1));
329 
330  EXPECT_DIF_BADARG(dif_otbn_dmem_read(&dif_otbn_, 0, test_data, 2));
331 }
332 
333 TEST_F(DmemReadTest, BadOffset) {
334  uint32_t test_data[2] = {0};
335 
336  // `offset` must be 32b-aligned.
338  dif_otbn_dmem_read(&dif_otbn_, 1, test_data, sizeof(test_data)));
339 
341  dif_otbn_dmem_read(&dif_otbn_, 2, test_data, sizeof(test_data)));
342 }
343 
344 TEST_F(DmemReadTest, SuccessWithoutOffset) {
345  // Assumption in the test.
346  ASSERT_GE(OTBN_DMEM_SIZE_BYTES, 8);
347 
348  uint32_t test_data[2] = {0};
349 
350  EXPECT_READ32(OTBN_DMEM_REG_OFFSET, 0x12345678);
351  EXPECT_READ32(OTBN_DMEM_REG_OFFSET + 4, 0xabcdef01);
352 
353  EXPECT_DIF_OK(dif_otbn_dmem_read(&dif_otbn_, 0, test_data, 8));
354  EXPECT_EQ(test_data[0], 0x12345678);
355  EXPECT_EQ(test_data[1], 0xabcdef01);
356 }
357 
358 TEST_F(DmemReadTest, SuccessWithOffset) {
359  // Assumption in the test.
360  ASSERT_GE(OTBN_DMEM_SIZE_BYTES, 12);
361 
362  uint32_t test_data[2] = {0};
363 
364  EXPECT_READ32(OTBN_DMEM_REG_OFFSET + 4, 0x12345678);
365  EXPECT_READ32(OTBN_DMEM_REG_OFFSET + 8, 0xabcdef01);
366 
367  EXPECT_DIF_OK(dif_otbn_dmem_read(&dif_otbn_, 4, test_data, 8));
368  EXPECT_EQ(test_data[0], 0x12345678);
369  EXPECT_EQ(test_data[1], 0xabcdef01);
370 }
371 
373 
374 TEST_F(ControlSoftwareErrorsFatalTest, NullArgs) {
376 }
377 
378 TEST_F(ControlSoftwareErrorsFatalTest, Success) {
379  EXPECT_WRITE32(OTBN_CTRL_REG_OFFSET, 0x1);
380  EXPECT_READ32(OTBN_CTRL_REG_OFFSET, 0x1);
381 
383 }
384 
385 TEST_F(ControlSoftwareErrorsFatalTest, Failure) {
386  EXPECT_WRITE32(OTBN_CTRL_REG_OFFSET, 0x0);
387  EXPECT_READ32(OTBN_CTRL_REG_OFFSET, 0x1);
388 
389  EXPECT_EQ(dif_otbn_set_ctrl_software_errs_fatal(&dif_otbn_, false),
391 }
392 
393 } // namespace
394 } // namespace dif_otbn_unittest