Software APIs
entropy_src_fw_ovr_test.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 
10 #include "sw/device/lib/testing/entropy_src_testutils.h"
11 #include "sw/device/lib/testing/entropy_testutils.h"
12 #include "sw/device/lib/testing/test_framework/check.h"
14 
15 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" // Generated.
16 
17 OTTF_DEFINE_TEST_CONFIG();
18 
19 enum {
20  /**
21  * The size of the buffer used in firmware to process the entropy bits in
22  * firmware override mode.
23  */
24  kEntropyFifoBufferSize = 16,
25 };
26 
27 /**
28  * Flushes the data entropy buffer until there is no data available to read.
29  *
30  * Asserts test error if any of the returned words is equal to zero. Logs the
31  * number of entropy words flushed in a single call.
32  *
33  * @param entropy An entropy source instance.
34  */
35 static void entropy_data_flush(dif_entropy_src_t *entropy_src) {
36  uint32_t entropy_bits;
37  uint32_t read_count = 0;
38 
39  // TODO: Remove this limit. Entropy source should block if there is no entropy
40  // available in FW override mode.
41  const uint32_t kMaxReadCount = 12;
42 
43  while (dif_entropy_src_is_entropy_available(entropy_src) == kDifOk) {
44  CHECK_DIF_OK(dif_entropy_src_non_blocking_read(entropy_src, &entropy_bits));
45  CHECK(entropy_bits != 0);
46  read_count++;
47  if (read_count >= kMaxReadCount) {
48  break;
49  }
50  }
51  LOG_INFO("Flushed %d entropy words.", read_count);
52 }
53 
54 /**
55  * Test the firmware override path.
56  *
57  * This tests disconnects the observation buffer from the entropy src
58  * pre-conditioner block to read the raw entropy data after the hardware
59  * health tests. It then feeds the data back into the conditioner block until
60  * there is data available in the output FIFO.
61  *
62  * @param entropy An Entropy handle.
63  */
64 void test_firmware_override(dif_entropy_src_t *entropy) {
65  CHECK_STATUS_OK(entropy_testutils_stop_all());
66  CHECK_STATUS_OK(
67  entropy_src_testutils_fw_override_enable(entropy, kEntropyFifoBufferSize,
68  /*route_to_firmware=*/true,
69  /*bypass_conditioner=*/false));
70  entropy_data_flush(entropy);
71 
72  // Read data from the observation FIFO and write it back into the
73  // pre-conditioner until there is data available in the output buffer.
74  uint32_t buf[kEntropyFifoBufferSize] = {0};
75  uint32_t word_count = 0;
76  do {
78  entropy, buf, kEntropyFifoBufferSize));
79  for (size_t i = 0; i < kEntropyFifoBufferSize; ++i) {
80  CHECK(buf[i] != 0);
81  }
82  // Start the SHA3 process so that it is ready to accept entropy data.
84  entropy, kDifToggleEnabled));
86  entropy, buf, kEntropyFifoBufferSize, NULL));
87  word_count += kEntropyFifoBufferSize;
88  // Stop insertion so that the SHA3 can process data.
90  entropy, kDifToggleDisabled));
92  LOG_INFO("Processed %d words via FIFO_OVR buffer.", word_count);
93  entropy_data_flush(entropy);
94 }
95 
96 bool test_main(void) {
97  dif_entropy_src_t entropy_src;
98  CHECK_DIF_OK(dif_entropy_src_init(
100  test_firmware_override(&entropy_src);
101  return true;
102 }