Software APIs
edn_auto_mode.c
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 
5 #include "hw/ip/aes/model/aes_modes.h"
11 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
14 #include "sw/device/lib/testing/aes_testutils.h"
15 #include "sw/device/lib/testing/edn_testutils.h"
16 #include "sw/device/lib/testing/entropy_testutils.h"
18 #include "sw/device/lib/testing/rand_testutils.h"
19 #include "sw/device/lib/testing/test_framework/check.h"
21 #include "sw/device/tests/otbn_randomness_impl.h"
22 
23 #include "edn_regs.h" // Generated
25 
26 enum {
27  kTimeout = (10 * 1000 * 1000),
28  kOtbnRounds = 2,
29  kOtbnRandomnessIterations = 1,
30  kTestProcedureRepetitions = 2,
31 };
32 
33 static dif_csrng_t csrng;
34 static dif_edn_t edn0;
35 static dif_edn_t edn1;
36 static dif_aes_t aes;
37 static dif_otbn_t otbn;
38 static dif_rv_core_ibex_t rv_core_ibex;
39 
40 // AES ECB encryption transaction.
41 static dif_aes_transaction_t transaction = {
42  .operation = kDifAesOperationEncrypt,
43  .mode = kDifAesModeEcb,
44  .key_len = kDifAesKey256,
45  .key_provider = kDifAesKeySoftwareProvided,
46  .mask_reseeding = kDifAesReseedPerBlock,
47  .manual_operation = kDifAesManualOperationAuto,
48  .reseed_on_key_change = true,
49  .ctrl_aux_lock = false,
50 };
51 
52 OTTF_DEFINE_TEST_CONFIG();
53 
54 // Initializes the peripherals used in this test.
55 static void init_peripherals(void) {
56  CHECK_DIF_OK(dif_csrng_init(
58  CHECK_DIF_OK(
60  CHECK_DIF_OK(
62  CHECK_DIF_OK(
64  CHECK_DIF_OK(
65  dif_otbn_init(mmio_region_from_addr(TOP_EARLGREY_OTBN_BASE_ADDR), &otbn));
66  CHECK_DIF_OK(dif_rv_core_ibex_init(
68  &rv_core_ibex));
69 }
70 
71 static void configure_otbn(void) {
72  otbn_randomness_test_prepare(&otbn, kOtbnRandomnessIterations);
73 }
74 
75 // configure the entropy complex
76 static void entropy_config(void) {
77  dif_edn_auto_params_t edn_params0 =
78  edn_testutils_auto_params_build(false, /*res_itval=*/0, /*glen_val=*/0);
79  dif_edn_auto_params_t edn_params1 =
80  edn_testutils_auto_params_build(false, /*res_itval=*/0, /*glen_val=*/0);
81  // Disable the entropy complex
82  CHECK_STATUS_OK(entropy_testutils_stop_all());
83  // Enable ENTROPY_SRC in FIPS mode
84  CHECK_STATUS_OK(entropy_testutils_entropy_src_init());
85  // Enable CSRNG
86  CHECK_DIF_OK(dif_csrng_configure(&csrng));
87  // Enable EDNs in auto request mode
88  CHECK_DIF_OK(dif_edn_set_auto_mode(&edn0, edn_params0));
89  CHECK_DIF_OK(dif_edn_set_auto_mode(&edn1, edn_params1));
90  CHECK_DIF_OK(dif_aes_reset(&aes));
91 }
92 
93 static status_t stress_test_edns(void) {
94  int otbn_execute_rounds = kOtbnRounds;
95  dif_rv_core_ibex_rnd_status_t ibex_rnd_status;
96  dif_otbn_status_t otbn_status;
97  uint32_t ibex_rnd_data;
98  dif_aes_data_t out_data;
99  // Start AES at least once.
100  LOG_INFO("aes_testutils_setup_encryption round %d", otbn_execute_rounds);
101  CHECK_STATUS_OK(aes_testutils_setup_encryption(transaction, &aes));
102  while (otbn_execute_rounds) {
103  LOG_INFO("dif_otbn_get_status round %d", otbn_execute_rounds);
104  CHECK_DIF_OK(dif_otbn_get_status(&otbn, &otbn_status));
105  if (otbn_status == kDifOtbnStatusIdle) {
106  LOG_INFO("otbn_testutils_execute round %d", otbn_execute_rounds);
107  CHECK_STATUS_OK(otbn_testutils_execute(&otbn));
108  otbn_execute_rounds--;
109  }
110  if (aes_testutils_get_status(&aes, kDifAesStatusOutputValid)) {
111  LOG_INFO("dif_aes_read_output round %d", otbn_execute_rounds);
112  // Read out the produced cipher text.
113  CHECK_DIF_OK(dif_aes_read_output(&aes, &out_data));
114  LOG_INFO("aes_testutils_setup_encryption round %d", otbn_execute_rounds);
115  // Start a new AES encryption.
116  CHECK_STATUS_OK(aes_testutils_setup_encryption(transaction, &aes));
117  }
118 
119  CHECK_DIF_OK(
120  dif_rv_core_ibex_get_rnd_status(&rv_core_ibex, &ibex_rnd_status));
121  if (ibex_rnd_status == kDifRvCoreIbexRndStatusValid)
122  CHECK_DIF_OK(
123  dif_rv_core_ibex_read_rnd_data(&rv_core_ibex, &ibex_rnd_data));
124  }
125  // Verify that all entropy consuming endpoints can finish their operations
126  // and do not hang.
127  CHECK_STATUS_OK(otbn_testutils_wait_for_done(&otbn, kDifOtbnErrBitsNoError));
128  AES_TESTUTILS_WAIT_FOR_STATUS(&aes, kDifAesStatusOutputValid, true, kTimeout);
129  IBEX_TRY_SPIN_FOR(rv_core_ibex_testutils_is_rnd_data_valid(&rv_core_ibex),
130  kTimeout);
131 
132  return OK_STATUS();
133 }
134 
135 bool test_main(void) {
136  int repetitions = kTestProcedureRepetitions;
137  LOG_INFO("init_peripherals start");
138  init_peripherals();
139  // Prepare the OTBN for execution.
140  configure_otbn();
141  // Start the procedure multiple times, with different EDN configurations.
142  while (repetitions) {
143  // Disable and restart the entropy complex.
144  LOG_INFO("entropy_config start");
145  entropy_config();
146  // Trigger the execution of the OTBN, AES and IBEX, consuming entropy
147  // to stress test the EDNs.
148  LOG_INFO("stress_test_edns start");
149  stress_test_edns();
150  repetitions--;
151  }
152 
153  return true;
154 }