Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sival] Backport entropy_src_fw_override_test to earlgrey_es_sival #21810

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion sw/device/lib/dif/dif_entropy_src.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,21 @@ dif_result_t dif_entropy_src_fw_override_configure(
return kDifOk;
}

dif_result_t dif_entropy_src_fw_override_sha3_start_insert(
const dif_entropy_src_t *entropy_src, dif_toggle_t enabled) {
if (entropy_src == NULL) {
return kDifBadArg;
}

uint32_t reg = bitfield_field32_write(
0, ENTROPY_SRC_FW_OV_SHA3_START_FW_OV_INSERT_START_FIELD,
dif_toggle_to_multi_bit_bool4(enabled));
mmio_region_write32(entropy_src->base_addr,
ENTROPY_SRC_FW_OV_SHA3_START_REG_OFFSET, reg);

return kDifOk;
}

dif_result_t dif_entropy_src_health_test_configure(
const dif_entropy_src_t *entropy_src,
dif_entropy_src_health_test_config_t config) {
Expand Down Expand Up @@ -539,7 +554,7 @@ dif_result_t dif_entropy_src_observe_fifo_nonblocking_read(
return kDifOk;
}

dif_result_t dif_entropy_src_observe_fifo_write(
dif_result_t dif_entropy_src_fw_ov_data_write(
const dif_entropy_src_t *entropy_src, const uint32_t *buf, size_t len,
size_t *written) {
if (entropy_src == NULL || buf == NULL) {
Expand Down
29 changes: 22 additions & 7 deletions sw/device/lib/dif/dif_entropy_src.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ typedef enum dif_entropy_src_main_fsm {
*/
typedef struct dif_entropy_src_fw_override_config {
/**
* Enables firmware to insert entropy bits back into the pre-conditioner block
* via `dif_entropy_fifo_write()` calls. This feature is useful when the
* firmware is required to implement additional health checks, and to perform
* known answer tests of the preconditioner function.
* Enables firmware to insert entropy bits back into the pre-conditioner FIFO
* via `dif_entropy_src_fw_ov_data_write()` calls. This feature is useful when
* the firmware is required to implement additional health checks, and to
* perform known answer tests of the conditioner.
*
* To take effect, this requires the firmware override feature to be enabled.
*/
Expand Down Expand Up @@ -534,6 +534,21 @@ dif_result_t dif_entropy_src_fw_override_configure(
const dif_entropy_src_t *entropy_src,
dif_entropy_src_fw_override_config_t config, dif_toggle_t enabled);

/**
* Configures whether to start the entropy source's SHA3 process and be ready to
* accept entropy data.
*
* This is used in firmware override mode and should be enabled before writing
* to the override FIFO. Disable this after writing has finished to ensure the
* SHA3 block finishes processing and pushes the results to the `esfinal` FIFO.
*
* @param entropy_src An entropy source handle.
* @param enabled Whether to start the SHA3 process.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_entropy_src_fw_override_sha3_start_insert(
const dif_entropy_src_t *entropy_src, dif_toggle_t enabled);

/**
* Configures an entropy source health test feature with runtime information.
*
Expand Down Expand Up @@ -679,7 +694,7 @@ dif_result_t dif_entropy_src_observe_fifo_nonblocking_read(
const dif_entropy_src_t *entropy_src, uint32_t *buf, size_t *len);

/**
* Performs a write to the entropy pipeline through the observe FIFO.
* Performs a write to the entropy pipeline through the firmware override FIFO.
*
* Entropy source must be configured with firmware override and insert mode
* enabled, otherwise the function will return `kDifError`.
Expand All @@ -691,14 +706,14 @@ dif_result_t dif_entropy_src_observe_fifo_nonblocking_read(
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_entropy_src_observe_fifo_write(
dif_result_t dif_entropy_src_fw_ov_data_write(
const dif_entropy_src_t *entropy_src, const uint32_t *buf, size_t len,
size_t *written);

/**
* Starts conditioner operation.
*
* Initializes the conditioner. Use the `dif_entropy_src_observe_fifo_write()`
* Initializes the conditioner. Use the `dif_entropy_src_fw_ov_data_write()`
* function to send data to the conditioner, and
* `dif_entropy_src_conditioner_stop()` once ready to stop the conditioner
* operation.
Expand Down
15 changes: 7 additions & 8 deletions sw/device/lib/dif/dif_entropy_src_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -570,12 +570,11 @@ class ObserveFifoWriteTest : public EntropySrcTest {};

TEST_F(ObserveFifoWriteTest, NullArgs) {
uint32_t buf[8] = {0};
EXPECT_DIF_BADARG(dif_entropy_src_fw_ov_data_write(nullptr, buf, 8, nullptr));
EXPECT_DIF_BADARG(
dif_entropy_src_observe_fifo_write(nullptr, buf, 8, nullptr));
dif_entropy_src_fw_ov_data_write(&entropy_src_, nullptr, 8, nullptr));
EXPECT_DIF_BADARG(
dif_entropy_src_observe_fifo_write(&entropy_src_, nullptr, 8, nullptr));
EXPECT_DIF_BADARG(
dif_entropy_src_observe_fifo_write(nullptr, nullptr, 8, nullptr));
dif_entropy_src_fw_ov_data_write(nullptr, nullptr, 8, nullptr));
}

TEST_F(ObserveFifoWriteTest, BadConfig) {
Expand All @@ -587,7 +586,7 @@ TEST_F(ObserveFifoWriteTest, BadConfig) {
{{ENTROPY_SRC_FW_OV_CONTROL_FW_OV_ENTROPY_INSERT_OFFSET,
kMultiBitBool4False},
{ENTROPY_SRC_FW_OV_CONTROL_FW_OV_MODE_OFFSET, kMultiBitBool4False}});
EXPECT_EQ(dif_entropy_src_observe_fifo_write(&entropy_src_, buf, 8, nullptr),
EXPECT_EQ(dif_entropy_src_fw_ov_data_write(&entropy_src_, buf, 8, nullptr),
kDifError);

// Entropy insert mode not set.
Expand All @@ -596,7 +595,7 @@ TEST_F(ObserveFifoWriteTest, BadConfig) {
{{ENTROPY_SRC_FW_OV_CONTROL_FW_OV_ENTROPY_INSERT_OFFSET,
kMultiBitBool4False},
{ENTROPY_SRC_FW_OV_CONTROL_FW_OV_MODE_OFFSET, kMultiBitBool4True}});
EXPECT_EQ(dif_entropy_src_observe_fifo_write(&entropy_src_, buf, 8, nullptr),
EXPECT_EQ(dif_entropy_src_fw_ov_data_write(&entropy_src_, buf, 8, nullptr),
kDifError);
}

Expand All @@ -609,7 +608,7 @@ TEST_F(ObserveFifoWriteTest, FifoFull) {
kMultiBitBool4True},
{ENTROPY_SRC_FW_OV_CONTROL_FW_OV_MODE_OFFSET, kMultiBitBool4True}});
EXPECT_READ32(ENTROPY_SRC_FW_OV_WR_FIFO_FULL_REG_OFFSET, 1);
EXPECT_EQ(dif_entropy_src_observe_fifo_write(&entropy_src_, buf, 4, &written),
EXPECT_EQ(dif_entropy_src_fw_ov_data_write(&entropy_src_, buf, 4, &written),
kDifIpFifoFull);
EXPECT_EQ(written, 0);
}
Expand All @@ -627,7 +626,7 @@ TEST_F(ObserveFifoWriteTest, Success) {
EXPECT_WRITE32(ENTROPY_SRC_FW_OV_WR_DATA_REG_OFFSET, i + 1);
}
EXPECT_DIF_OK(
dif_entropy_src_observe_fifo_write(&entropy_src_, buf, 4, &written));
dif_entropy_src_fw_ov_data_write(&entropy_src_, buf, 4, &written));
EXPECT_EQ(written, 4);
}

Expand Down
35 changes: 35 additions & 0 deletions sw/device/lib/testing/entropy_testutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,23 @@ status_t entropy_testutils_wait_for_state(const dif_entropy_src_t *entropy_src,
return OK_STATUS();
}

status_t entropy_testutils_drain_observe_fifo(dif_entropy_src_t *entropy_src) {
// This value is arbitrary, it could be 1 but since there is some
// overhead in dif_entropy_src_observe_fifo_nonblocking_read, it's better
// to read several words every time to drain the FIFO quickly.
const size_t kDrainCount = 32;
size_t len;
// Read from the FIFO until we get a short read which means that the FIFO was
// emptied.
do {
len = kDrainCount;
TRY(dif_entropy_src_observe_fifo_nonblocking_read(entropy_src, NULL, &len));
} while (len == kDrainCount);
TRY(dif_entropy_src_clear_fifo_overflow(entropy_src));

return OK_STATUS();
}

status_t entropy_testutils_stop_all(void) {
const dif_entropy_src_t entropy_src = {
.base_addr = mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR)};
Expand All @@ -208,6 +225,24 @@ status_t entropy_testutils_stop_all(void) {
return OK_STATUS();
}

status_t entropy_testutils_disable_health_tests(
dif_entropy_src_t *entropy_src) {
static dif_entropy_src_test_t kHealthTest[] = {
kDifEntropySrcTestRepetitionCount,
kDifEntropySrcTestRepetitionCountSymbol,
kDifEntropySrcTestAdaptiveProportion, kDifEntropySrcTestBucket,
kDifEntropySrcTestMarkov};
for (size_t i = 0; i < ARRAYSIZE(kHealthTest); i++) {
TRY(dif_entropy_src_health_test_configure(
entropy_src,
(dif_entropy_src_health_test_config_t){.test_type = kHealthTest[i],
.high_threshold = 0xffffffff,
.low_threshold = 0}));
}

return OK_STATUS();
}

status_t entropy_testutils_error_check(const dif_entropy_src_t *entropy_src,
const dif_csrng_t *csrng,
const dif_edn_t *edn0,
Expand Down
13 changes: 13 additions & 0 deletions sw/device/lib/testing/entropy_testutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ status_t entropy_testutils_fw_override_enable(dif_entropy_src_t *entropy_src,
bool firmware_override_enable,
bool bypass_conditioner);

/**
* Drain the `entropy_src` FW override mode observe FIFO and clear overflow
* status if set.
*/
OT_WARN_UNUSED_RESULT
status_t entropy_testutils_drain_observe_fifo(dif_entropy_src_t *entropy_src);

/**
* Waits for the entropy_src to reach a certain state.
*
Expand All @@ -71,6 +78,12 @@ status_t entropy_testutils_wait_for_state(const dif_entropy_src_t *entropy_src,
OT_WARN_UNUSED_RESULT
status_t entropy_testutils_stop_all(void);

/**
* Disables all entropy source health tests.
*/
OT_WARN_UNUSED_RESULT
status_t entropy_testutils_disable_health_tests(dif_entropy_src_t *entropy_src);

/**
* Throws test assertion if there are any errors detected in any of the entropy
* blocks.
Expand Down
36 changes: 36 additions & 0 deletions sw/device/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -1330,10 +1330,13 @@ opentitan_test(
"//sw/device/lib/base:memory",
"//sw/device/lib/base:mmio",
"//sw/device/lib/dif:base",
"//sw/device/lib/dif:csrng",
"//sw/device/lib/dif:entropy_src",
"//sw/device/lib/dif:rv_core_ibex",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing:edn_testutils",
"//sw/device/lib/testing:entropy_testutils",
"//sw/device/lib/testing:rv_core_ibex_testutils",
"//sw/device/lib/testing/test_framework:ottf_main",
],
)
Expand Down Expand Up @@ -5204,3 +5207,36 @@ opentitan_test(
"//sw/device/lib/testing/test_framework:ottf_utils",
],
)

opentitan_test(
name = "entropy_src_fw_override_test",
srcs = ["entropy_src_fw_override_test.c"],
exec_env = dicts.add(
EARLGREY_TEST_ENVS,
EARLGREY_SILICON_OWNER_ROM_EXT_ENVS,
{
"//hw/top_earlgrey:silicon_creator": None,
},
),
deps = [
"//hw/ip/entropy_src/data:entropy_src_regs",
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/base:memory",
"//sw/device/lib/base:mmio",
"//sw/device/lib/dif:aes",
"//sw/device/lib/dif:base",
"//sw/device/lib/dif:csrng",
"//sw/device/lib/dif:entropy_src",
"//sw/device/lib/dif:hmac",
"//sw/device/lib/dif:kmac",
"//sw/device/lib/dif:rv_core_ibex",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing:aes_testutils",
"//sw/device/lib/testing:edn_testutils",
"//sw/device/lib/testing:entropy_testutils",
"//sw/device/lib/testing:hmac_testutils",
"//sw/device/lib/testing:kmac_testutils",
"//sw/device/lib/testing:rv_core_ibex_testutils",
"//sw/device/lib/testing/test_framework:ottf_main",
],
)
38 changes: 4 additions & 34 deletions sw/device/tests/entropy_src_fw_observe_many_contiguous.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,26 +69,6 @@ bool entropy_src_fifo_has_overflowed(void) {
return fifo_depth == ENTROPY_SRC_PARAM_OBSERVE_FIFO_DEPTH;
}

/**
* Drain observe FIFO and clear overflow status if set.
*/
static void drain_observe_fifo(void) {
// This value is arbitrary, it could be 1 but since there is some
// overhead in dif_entropy_src_observe_fifo_nonblocking_read, it's better
// to read several words every time to drain the FIFO quickly.
const size_t kDrainCount = 32;
size_t len;
// Read from the FIFO until we get a short read which means that the FIFO was
// emptied.
LOG_INFO("drain observe FIFO overflow...");
do {
len = kDrainCount;
CHECK_DIF_OK(dif_entropy_src_observe_fifo_nonblocking_read(&entropy_src,
NULL, &len));
} while (len == kDrainCount);
CHECK_DIF_OK(dif_entropy_src_clear_fifo_overflow(&entropy_src));
}

/**
* Let observe FIFO overflow.
*/
Expand All @@ -107,20 +87,9 @@ static status_t entropy_config(
edn_testutils_auto_params_build(false, /*res_itval=*/0, /*glen_val=*/0);
// Disable the entropy complex.
TRY(entropy_testutils_stop_all());

// Disable all health tests.
static dif_entropy_src_test_t kHealthTest[] = {
kDifEntropySrcTestRepetitionCount,
kDifEntropySrcTestRepetitionCountSymbol,
kDifEntropySrcTestAdaptiveProportion, kDifEntropySrcTestBucket,
kDifEntropySrcTestMarkov};
for (size_t i = 0; i < ARRAYSIZE(kHealthTest); i++) {
TRY(dif_entropy_src_health_test_configure(
&entropy_src,
(dif_entropy_src_health_test_config_t){.test_type = kHealthTest[i],
.high_threshold = 0xffffffff,
.low_threshold = 0}));
}
TRY(entropy_testutils_disable_health_tests(&entropy_src));

// Enable FW override.
TRY(dif_entropy_src_fw_override_configure(
&entropy_src,
Expand Down Expand Up @@ -173,7 +142,8 @@ status_t firmware_override_observe(
uint32_t words_to_read = nr_sample_words;
uint32_t *sample_buffer_ptr = sample_buffer;
// Drain FIFO to make sure we get contiguous samples.
drain_observe_fifo();
LOG_INFO("drain observe FIFO overflow...");
TRY(entropy_testutils_drain_observe_fifo(&entropy_src));
// Collect.
ibex_timeout_t tmo = ibex_timeout_init(timeout_usec);
while (words_to_read > 0 && !ibex_timeout_check(&tmo)) {
Expand Down
Loading
Loading