Skip to content

Commit

Permalink
[sw/entropy] Various clean-up to entropy_testutil
Browse files Browse the repository at this point in the history
- remove testutil's direct access to entropy complex registers
- added dis_entropy_src_stop to emulate the function in edn / csrng
- sever the dependency between entropy_testutil_boot_mode and auto_mode

- edn1 is currently set to reseed once every 4 generates, this is because
  if it were set to 1, artificial test conditions could end up significantly
  stalling entropy distribution due to lowRISC#14505.

Signed-off-by: Timothy Chen <[email protected]>
  • Loading branch information
Timothy Chen committed Aug 23, 2022
1 parent 6b7834c commit 73a921c
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 75 deletions.
10 changes: 10 additions & 0 deletions sw/device/lib/dif/dif_edn.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ dif_result_t dif_edn_is_locked(const dif_edn_t *edn, bool *is_locked) {
return kDifOk;
}

dif_result_t dif_edn_reset_config(const dif_edn_t *edn) {
if (edn == NULL) {
return kDifBadArg;
}
DIF_RETURN_IF_ERROR(check_locked(edn));
mmio_region_write32(edn->base_addr, EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);

return kDifOk;
}

dif_result_t dif_edn_set_boot_mode(const dif_edn_t *edn) {
if (edn == NULL) {
return kDifBadArg;
Expand Down
12 changes: 12 additions & 0 deletions sw/device/lib/dif/dif_edn.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,18 @@ dif_result_t dif_edn_lock(const dif_edn_t *edn);
OT_WARN_UNUSED_RESULT
dif_result_t dif_edn_is_locked(const dif_edn_t *edn, bool *is_locked);

/**
* Reset EDN configuration to default.
*
* Each call to this function should be sequenced with a call to
* `dif_edn_stop()`.
*
* @param edn An EDN handle.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_edn_reset_config(const dif_edn_t *edn);

/**
* Enables the EDN in boot-time mode.
*
Expand Down
36 changes: 35 additions & 1 deletion sw/device/lib/dif/dif_entropy_src.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,46 @@

#include "entropy_src_regs.h" // Generated.

dif_result_t dif_entropy_src_stop(const dif_entropy_src_t *entropy_src) {
if (entropy_src == NULL) {
return kDifBadArg;
}

mmio_region_write32(entropy_src->base_addr,
ENTROPY_SRC_MODULE_ENABLE_REG_OFFSET,
ENTROPY_SRC_MODULE_ENABLE_REG_RESVAL);

// once disabled, the entropy_src regwen is released
if (!mmio_region_read32(entropy_src->base_addr,
ENTROPY_SRC_REGWEN_REG_OFFSET)) {
return kDifLocked;
}

// set back to default value
mmio_region_write32(entropy_src->base_addr,
ENTROPY_SRC_ENTROPY_CONTROL_REG_OFFSET,
ENTROPY_SRC_ENTROPY_CONTROL_REG_RESVAL);

mmio_region_write32(entropy_src->base_addr, ENTROPY_SRC_CONF_REG_OFFSET,
ENTROPY_SRC_CONF_REG_RESVAL);

mmio_region_write32(entropy_src->base_addr,
ENTROPY_SRC_HEALTH_TEST_WINDOWS_REG_OFFSET,
ENTROPY_SRC_HEALTH_TEST_WINDOWS_REG_RESVAL);

mmio_region_write32(entropy_src->base_addr,
ENTROPY_SRC_ALERT_THRESHOLD_REG_OFFSET,
ENTROPY_SRC_ALERT_THRESHOLD_REG_RESVAL);

return kDifOk;
}

dif_result_t dif_entropy_src_configure(const dif_entropy_src_t *entropy_src,
dif_entropy_src_config_t config,
dif_toggle_t enabled) {
if (entropy_src == NULL ||
config.single_bit_mode > kDifEntropySrcSingleBitModeDisabled ||
!dif_is_valid_toggle(enabled)) {
!dif_is_valid_toggle(enabled) || config.health_test_window_size == 0) {
return kDifBadArg;
}

Expand Down
10 changes: 10 additions & 0 deletions sw/device/lib/dif/dif_entropy_src.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,16 @@ typedef enum dif_entropy_src_error {
kDifEntropySrcErrorHardenedCounter = 1U << 11,
} dif_entropy_src_error_t;

/**
* Stops the current mode of operation and disables the entropy_src module
*
*
* @param entropy_src An entropy source handle.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_entropy_src_stop(const dif_entropy_src_t *entropy_src);

/**
* Configures entropy source with runtime information.
*
Expand Down
5 changes: 3 additions & 2 deletions sw/device/lib/dif/dif_entropy_src_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class ConfigTest : public EntropySrcTest {
.fips_enable = false,
.route_to_firmware = false,
.single_bit_mode = kDifEntropySrcSingleBitModeDisabled,
.health_test_window_size = 1
};
};

Expand Down Expand Up @@ -154,10 +155,10 @@ INSTANTIATE_TEST_SUITE_P(
ConfigParams{false, false, kDifEntropySrcSingleBitMode3, false, 64, 2,
kDifToggleEnabled},
// Test alerts disabled.
ConfigParams{false, false, kDifEntropySrcSingleBitMode0, false, 0, 0,
ConfigParams{false, false, kDifEntropySrcSingleBitMode0, false, 1, 0,
kDifToggleDisabled},
// Test all disabled.
ConfigParams{false, false, kDifEntropySrcSingleBitMode0, false, 0, 2,
ConfigParams{false, false, kDifEntropySrcSingleBitMode0, false, 1, 2,
kDifToggleDisabled},
// Test all enabled.
ConfigParams{true, true, kDifEntropySrcSingleBitMode0, true, 32, 2,
Expand Down
106 changes: 36 additions & 70 deletions sw/device/lib/testing/entropy_testutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,38 @@
#include "sw/device/lib/dif/dif_entropy_src.h"
#include "sw/device/lib/testing/test_framework/check.h"

#include "edn_regs.h" // Generated
#include "entropy_src_regs.h" // Generated
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"

static void setup_entropy_src(const dif_entropy_src_t *entropy_src) {
const dif_entropy_src_config_t config = {
.fips_enable = true,
.route_to_firmware = false,
.single_bit_mode = kDifEntropySrcSingleBitModeDisabled,
.health_test_window_size = 0x0200, /*default*/
.alert_threshold = 2, /*default*/
};
CHECK_DIF_OK(
dif_entropy_src_configure(entropy_src, config, kDifToggleEnabled));
}

void entropy_testutils_auto_mode_init(void) {
const dif_entropy_src_t entropy_src = {
.base_addr = mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR)};
const dif_csrng_t csrng = {
.base_addr = mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR)};
const dif_edn_t edn0 = {
.base_addr = mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR)};
const dif_edn_t edn1 = {
.base_addr = mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR)};

// Disable CSRNG. This is required to abort the generate command of boot
// mode, which is likely still running.
CHECK_DIF_OK(dif_csrng_stop(&csrng));

// Stop both EDNs.
// Disable entropy complex
CHECK_DIF_OK(dif_edn_stop(&edn0));
CHECK_DIF_OK(dif_edn_stop(&edn1));
CHECK_DIF_OK(dif_csrng_stop(&csrng));
CHECK_DIF_OK(dif_entropy_src_stop(&entropy_src));

// Re-enable the CSRNG.
// re-eanble entropy src and csrng
setup_entropy_src(&entropy_src);
CHECK_DIF_OK(dif_csrng_configure(&csrng));

// Re-enable EDN0 in auto mode.
Expand Down Expand Up @@ -61,75 +72,30 @@ void entropy_testutils_auto_mode_init(void) {
{
.len = 1, .data = {0x00001003}, // One generate returns 1 block.
},
.reseed_interval = 1, // Reseed after every generate.
.reseed_interval = 4, // Reseed after every 4 generates.
};
CHECK_DIF_OK(dif_edn_set_auto_mode(&edn1, edn1_params));
}

static void setup_entropy_src(void) {
dif_entropy_src_t entropy_src;
CHECK_DIF_OK(dif_entropy_src_init(
mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR), &entropy_src));

// Disable entropy for test purpose, as it has been turned on by ROM
CHECK_DIF_OK(dif_entropy_src_set_enabled(&entropy_src, kDifToggleDisabled));

const dif_entropy_src_config_t config = {
.fips_enable = true,
.route_to_firmware = false,
.single_bit_mode = kDifEntropySrcSingleBitModeDisabled,
.health_test_window_size = 0x0200, /*default*/
.alert_threshold = 2, /*default*/
};
CHECK_DIF_OK(
dif_entropy_src_configure(&entropy_src, config, kDifToggleEnabled));
}
void entropy_testutils_boot_mode_init(void) {
const dif_entropy_src_t entropy_src = {
.base_addr = mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR)};
const dif_csrng_t csrng = {
.base_addr = mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR)};
const dif_edn_t edn0 = {
.base_addr = mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR)};
const dif_edn_t edn1 = {
.base_addr = mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR)};

static void setup_csrng(void) {
dif_csrng_t csrng;
CHECK_DIF_OK(dif_csrng_init(
mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR), &csrng));
CHECK_DIF_OK(dif_entropy_src_stop(&entropy_src));
CHECK_DIF_OK(dif_csrng_stop(&csrng));
CHECK_DIF_OK(dif_edn_stop(&edn0));
CHECK_DIF_OK(dif_edn_stop(&edn1));

setup_entropy_src(&entropy_src);
CHECK_DIF_OK(dif_csrng_configure(&csrng));
}

static void setup_edn() {
// Temporary solution to configure/enable the EDN and CSRNG to allow OTBN to
// run before a DIF is available,
// https://github.com/lowRISC/opentitan/issues/6082
// disable edn.
uint32_t reg = 0;
reg =
bitfield_field32_write(0, EDN_CTRL_EDN_ENABLE_FIELD, kMultiBitBool4False);
reg = bitfield_field32_write(reg, EDN_CTRL_BOOT_REQ_MODE_FIELD,
kMultiBitBool4False);
reg = bitfield_field32_write(reg, EDN_CTRL_AUTO_REQ_MODE_FIELD,
kMultiBitBool4False);
reg = bitfield_field32_write(reg, EDN_CTRL_CMD_FIFO_RST_FIELD,
kMultiBitBool4False);
mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
EDN_CTRL_REG_OFFSET, reg);
mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
EDN_CTRL_REG_OFFSET, reg);

reg =
bitfield_field32_write(0, EDN_CTRL_EDN_ENABLE_FIELD, kMultiBitBool4True);
reg = bitfield_field32_write(reg, EDN_CTRL_BOOT_REQ_MODE_FIELD,
kMultiBitBool4True);
reg = bitfield_field32_write(reg, EDN_CTRL_AUTO_REQ_MODE_FIELD,
kMultiBitBool4False);
reg = bitfield_field32_write(reg, EDN_CTRL_CMD_FIFO_RST_FIELD,
kMultiBitBool4False);
mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
EDN_CTRL_REG_OFFSET, reg);
mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
EDN_CTRL_REG_OFFSET, reg);
}

void entropy_testutils_boot_mode_init(void) {
setup_entropy_src();
setup_csrng();
setup_edn();
CHECK_DIF_OK(dif_edn_set_boot_mode(&edn0));
CHECK_DIF_OK(dif_edn_set_boot_mode(&edn1));
}

void entropy_testutils_wait_for_state(const dif_entropy_src_t *entropy_src,
Expand Down
2 changes: 0 additions & 2 deletions sw/device/tests/entropy_src_edn_reqs_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,6 @@ static void alert_handler_test(entropy_src_test_context_t *ctx) {
void test_initialize(entropy_src_test_context_t *ctx) {
LOG_INFO("%s", __func__);

entropy_testutils_boot_mode_init();

mmio_region_t addr =
mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR);
CHECK_DIF_OK(dif_entropy_src_init(addr, &ctx->entropy_src));
Expand Down

0 comments on commit 73a921c

Please sign in to comment.