13 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
15 #include "sw/device/lib/runtime/irq.h"
17 #include "sw/device/lib/testing/aes_testutils.h"
18 #include "sw/device/lib/testing/edn_testutils.h"
19 #include "sw/device/lib/testing/entropy_src_testutils.h"
20 #include "sw/device/lib/testing/entropy_testutils.h"
21 #include "sw/device/lib/testing/kmac_testutils.h"
22 #include "sw/device/lib/testing/rand_testutils.h"
23 #include "sw/device/lib/testing/rv_core_ibex_testutils.h"
24 #include "sw/device/lib/testing/test_framework/check.h"
26 #include "sw/device/tests/otbn_randomness_impl.h"
28 #include "entropy_src_regs.h"
31 OTTF_DEFINE_TEST_CONFIG();
34 kEntropySrcHealthTestWindowSize = 0x200,
38 kEntropySrcFifoThreshold = 16,
42 kContiguousSamplesCount = 1024,
51 kFifoBufferSizeWords =
52 kContiguousSamplesCount * kBitsPerSample /
sizeof(uint32_t),
69 kEntropyFifoBufferSize = 12,
73 kRandomNumberCount = 16,
77 kRandomNumberTimeoutUsec = 100 * 1000,
83 kVerilatorRandomNumberTimeoutUsec = 48 * 100 * 1000,
87 kAesTestutilsTimeoutUsec = 1 * 1000 * 1000,
93 kVerilatorAesTestutilsTimeoutUsec = 48 * 1000 * 1000,
97 static dif_csrng_t csrng;
98 static dif_edn_t edn0;
99 static dif_edn_t edn1;
100 static dif_entropy_src_t entropy_src;
101 static dif_kmac_t kmac;
102 static dif_otbn_t otbn;
103 static dif_rv_core_ibex_t rv_core_ibex;
104 static dif_rv_plic_t rv_plic;
115 static uint32_t sample_buf_0[kFifoBufferSizeWords];
116 static uint32_t sample_buf_1[kFifoBufferSizeWords];
120 static uint32_t *input_buf = sample_buf_0;
121 static uint32_t *output_buf = sample_buf_1 + kFifoBufferSizeWords;
125 static size_t words_to_input = kFifoBufferSizeWords;
126 static size_t words_to_output = 0;
131 static bool fw_ov_insert_wait_enabled =
false;
142 bool entropy_src_fifo_has_overflowed(
void) {
145 return fifo_depth == ENTROPY_SRC_PARAM_OBSERVE_FIFO_DEPTH;
148 void ottf_external_isr(uint32_t *exc_info) {
160 if (words_to_input > 0 && entropy_src_fifo_has_overflowed()) {
161 CHECK_STATUS_OK(entropy_src_testutils_drain_observe_fifo(&entropy_src));
163 input_buf -= (kFifoBufferSizeWords - words_to_input);
164 words_to_input = kFifoBufferSizeWords;
167 if (words_to_input > 0) {
171 size_t len = words_to_input;
172 if (len > kEntropySrcFifoThreshold) {
173 len = kEntropySrcFifoThreshold;
177 &entropy_src, input_buf, &len));
180 words_to_input -= len;
185 if (words_to_input == 0 && words_to_output == 0) {
187 uint32_t *output_tmp = output_buf;
188 output_buf = input_buf - kFifoBufferSizeWords;
189 input_buf = output_tmp - kFifoBufferSizeWords;
191 words_to_input = kFifoBufferSizeWords;
192 words_to_output = kFifoBufferSizeWords;
195 if (fw_ov_insert_wait_enabled) {
199 if (words_to_output > 0) {
201 size_t len = words_to_output;
202 if (len > kMaxOutputWords) {
203 len = kMaxOutputWords;
210 size_t words_written = 0;
214 output_buf += words_written;
215 words_to_output -= words_written;
223 CHECK_DIF_OK(dif_entropy_src_irq_acknowledge(
224 &entropy_src, kDifEntropySrcIrqEsObserveFifoReady));
230 static status_t configure_interrupts(
void) {
241 TRY(dif_entropy_src_irq_set_enabled(
250 bool bypass_conditioner) {
253 irq_external_ctrl(
false);
255 LOG_INFO(
"Disabling entropy complex");
257 TRY(entropy_testutils_stop_all());
259 TRY(entropy_src_testutils_disable_health_tests(&entropy_src));
265 .entropy_insert_enable =
true,
266 .buffer_threshold = kEntropySrcFifoThreshold,
271 LOG_INFO(
"Enabling entropy source");
278 .route_to_firmware =
false,
279 .bypass_conditioner = bypass_conditioner,
280 .single_bit_mode = single_bit_mode,
281 .health_test_threshold_scope =
false,
282 .health_test_window_size = kEntropySrcHealthTestWindowSize,
283 .alert_threshold = UINT16_MAX},
287 irq_external_ctrl(
true);
298 LOG_INFO(
"Entropy complex configured");
304 static status_t reenable_entropy_src(
306 bool bypass_conditioner) {
308 bool entropy_req_intr =
false;
309 size_t words_written = 0;
310 uint32_t kInputMsg[kEntropyFifoBufferSize];
315 irq_external_ctrl(
false);
322 data = mmio_region_read32(entropy_src.base_addr,
323 ENTROPY_SRC_FW_OV_WR_FIFO_FULL_REG_OFFSET);
333 for (
int i = 0; i < kEntropyFifoBufferSize; i++) {
334 kInputMsg[i] = cnt++;
337 &entropy_src, (
const uint32_t *)kInputMsg, kEntropyFifoBufferSize,
344 CHECK_DIF_OK(dif_csrng_irq_acknowledge_state(
345 &csrng, 1 << CSRNG_INTR_STATE_CS_ENTROPY_REQ_BIT));
346 CHECK_DIF_OK(dif_csrng_irq_is_pending(
347 &csrng, CSRNG_INTR_STATE_CS_ENTROPY_REQ_BIT, &entropy_req_intr));
348 }
while (entropy_req_intr);
356 if (rv_core_ibex_testutils_is_rnd_data_valid(&rv_core_ibex)) {
357 TRY(dif_rv_core_ibex_read_rnd_data(&rv_core_ibex, &data));
359 CHECK_DIF_OK(dif_csrng_irq_is_pending(
360 &csrng, CSRNG_INTR_STATE_CS_ENTROPY_REQ_BIT, &entropy_req_intr));
361 }
while (!entropy_req_intr);
368 irq_external_ctrl(
true);
377 status_t firmware_override_extract_insert(
381 LOG_INFO(
"Configuring single_bit_mode=%u, bypass_conditioner=%d",
382 single_bit_mode, bypass_conditioner);
384 entropy_config(single_bit_mode, bypass_conditioner);
387 LOG_INFO(
"Generating random numbers...");
388 uint32_t rnd_timeout_usec = kRandomNumberTimeoutUsec;
393 rnd_timeout_usec = kVerilatorRandomNumberTimeoutUsec;
396 for (
size_t i = 0; i < kRandomNumberCount; i++) {
397 TRY(rv_core_ibex_testutils_get_rnd_data(&rv_core_ibex,
405 reenable_entropy_src(single_bit_mode, bypass_conditioner);
416 .reseed_on_key_change =
true,
417 .ctrl_aux_lock =
false,
421 uint32_t aes_timeout_usec = kAesTestutilsTimeoutUsec;
426 aes_timeout_usec = kVerilatorAesTestutilsTimeoutUsec;
428 TRY(aes_testutils_setup_encryption(transaction, &aes));
431 TRY(aes_testutils_decrypt_ciphertext(transaction, &aes));
436 .entropy_fast_process =
false,
438 .entropy_hash_threshold = 1,
439 .entropy_wait_timer = 0,
440 .entropy_prescaler = 0,
441 .message_big_endian =
false,
442 .output_big_endian =
false,
449 .share0 = {0x43424140, 0x47464544, 0x4B4A4948, 0x4F4E4D4C, 0x53525150,
450 0x57565554, 0x5B5A5958, 0x5F5E5D5C},
462 otbn_randomness_test_start(&otbn, 10);
463 TRY_CHECK(otbn_randomness_test_end(&otbn,
false));
472 CHECK_DIF_OK(dif_aes_init(base_addr, &aes));
474 CHECK_DIF_OK(dif_csrng_init(base_addr, &csrng));
476 CHECK_DIF_OK(dif_edn_init(base_addr, &edn0));
478 CHECK_DIF_OK(dif_edn_init(base_addr, &edn1));
480 CHECK_DIF_OK(dif_entropy_src_init(base_addr, &entropy_src));
482 CHECK_DIF_OK(dif_kmac_init(base_addr, &kmac));
484 CHECK_DIF_OK(dif_otbn_init(base_addr, &otbn));
486 CHECK_DIF_OK(dif_rv_core_ibex_init(base_addr, &rv_core_ibex));
488 CHECK_DIF_OK(dif_rv_plic_init(base_addr, &rv_plic));
490 LOG_INFO(
"Configuring interrupts...");
491 configure_interrupts();
492 irq_global_ctrl(
true);
493 irq_external_ctrl(
false);
495 LOG_INFO(
"Computing EDN parameters");
496 edn_params0 = edn_testutils_auto_params_build(
498 edn_params1 = edn_testutils_auto_params_build(
508 size_t entropy_src_mode_count =
ARRAYSIZE(kModes);
514 entropy_src_mode_count = 2;
519 for (
size_t i = 0; i < entropy_src_mode_count; i++) {
520 EXECUTE_TEST(test_result, firmware_override_extract_insert, kModes[i],
522 EXECUTE_TEST(test_result, firmware_override_extract_insert, kModes[i],
true,
528 EXECUTE_TEST(test_result, firmware_override_extract_insert,
530 EXECUTE_TEST(test_result, firmware_override_extract_insert,
538 return status_ok(test_result);
543 fw_ov_insert_wait_enabled =
true;
544 EXECUTE_TEST(test_result, firmware_override_extract_insert,
546 EXECUTE_TEST(test_result, firmware_override_extract_insert,
549 return status_ok(test_result);