Skip to content

Commit

Permalink
[pentest] Make iCache/dummy instr. enable/disable configurable
Browse files Browse the repository at this point in the history
Previously, in all pentests, the icache as well as the dummy instructions
were disabled to achieve constant timing between test runs. However, for
certain tests, we want to test the default iCache and dummy instruction
configuration that has been set in the ROM.

Signed-off-by: Pascal Nasahl <[email protected]>
  • Loading branch information
nasahlpa committed Mar 6, 2025
1 parent d2c2669 commit e4cccb7
Show file tree
Hide file tree
Showing 17 changed files with 95 additions and 23 deletions.
5 changes: 4 additions & 1 deletion sw/device/tests/penetrationtests/firmware/fi/crypto_fi.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ status_t handle_crypto_fi_aes(ujson_t *uj) {
}

status_t handle_crypto_fi_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

pentest_select_trigger_type(kPentestTriggerTypeSw);
pentest_init(kPentestTriggerSourceAes,
kPentestPeripheralIoDiv4 | kPentestPeripheralAes |
Expand All @@ -239,7 +242,7 @@ status_t handle_crypto_fi_init(ujson_t *uj) {
pentest_configure_alert_handler();

// Disable the instruction cache and dummy instructions for FI attacks.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

// Init the AES block.
TRY(dif_aes_init(mmio_region_from_addr(TOP_EARLGREY_AES_BASE_ADDR), &aes));
Expand Down
5 changes: 4 additions & 1 deletion sw/device/tests/penetrationtests/firmware/fi/ibex_fi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2371,6 +2371,9 @@ status_t handle_ibex_fi_char_unrolled_reg_op_loop_chain(ujson_t *uj) {
}

status_t handle_ibex_fi_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

pentest_select_trigger_type(kPentestTriggerTypeSw);
// As we are using the software defined trigger, the first argument of
// pentest_init is not needed. kPentestTriggerSourceAes is selected as a
Expand All @@ -2386,7 +2389,7 @@ status_t handle_ibex_fi_init(ujson_t *uj) {
pentest_configure_alert_handler();

// Disable the instruction cache and dummy instructions for FI attacks.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

// Enable the flash.
flash_info = dif_flash_ctrl_get_device_info();
Expand Down
5 changes: 4 additions & 1 deletion sw/device/tests/penetrationtests/firmware/fi/lc_ctrl_fi.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ static dif_rv_core_ibex_t rv_core_ibex;
static dif_lc_ctrl_t lc;

status_t handle_lc_ctrl_fi_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

pentest_select_trigger_type(kPentestTriggerTypeSw);
// As we are using the software defined trigger, the first argument of
// pentest_init is not needed. kPentestTriggerSourceAes is selected as a
Expand All @@ -32,7 +35,7 @@ status_t handle_lc_ctrl_fi_init(ujson_t *uj) {
kPentestPeripheralIoDiv4 | kPentestPeripheralCsrng);

// Disable the instruction cache and dummy instructions for FI attacks.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

// Configure Ibex to allow reading ERR_STATUS register.
TRY(dif_rv_core_ibex_init(
Expand Down
5 changes: 4 additions & 1 deletion sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,9 @@ status_t handle_otbn_fi_char_unrolled_reg_op_loop(ujson_t *uj) {
}

status_t handle_otbn_fi_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

// Configure the entropy complex for OTBN. Set the reseed interval to max
// to avoid a non-constant trigger window.
TRY(pentest_configure_entropy_source_max_reseed_interval());
Expand All @@ -1165,7 +1168,7 @@ status_t handle_otbn_fi_init(ujson_t *uj) {
pentest_configure_alert_handler();

// Disable the instruction cache and dummy instructions for FI attacks.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

// The load integrity, key sideloading, and char_mem tests get initialized at
// the first run.
Expand Down
5 changes: 4 additions & 1 deletion sw/device/tests/penetrationtests/firmware/fi/otp_fi.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ status_t handle_otp_fi_hw_cfg(ujson_t *uj) {
}

status_t handle_otp_fi_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

pentest_select_trigger_type(kPentestTriggerTypeSw);
// As we are using the software defined trigger, the first argument of
// pentest_init is not needed. kPentestTriggerSourceAes is selected as a
Expand All @@ -154,7 +157,7 @@ status_t handle_otp_fi_init(ujson_t *uj) {
pentest_configure_alert_handler();

// Disable the instruction cache and dummy instructions for FI attacks.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

TRY(dif_otp_ctrl_init(
mmio_region_from_addr(TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR), &otp));
Expand Down
10 changes: 8 additions & 2 deletions sw/device/tests/penetrationtests/firmware/fi/rng_fi.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,9 @@ status_t handle_rng_fi_edn_resp_ack(ujson_t *uj) {
}

status_t handle_rng_fi_edn_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

pentest_select_trigger_type(kPentestTriggerTypeSw);
// As we are using the software defined trigger, the first argument of
// pentest_init is not needed. kPentestTriggerSourceAes is selected as a
Expand All @@ -395,7 +398,7 @@ status_t handle_rng_fi_edn_init(ujson_t *uj) {
kPentestPeripheralCsrng | kPentestPeripheralEdn);

// Disable the instruction cache and dummy instructions for FI attacks.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

// Configure Ibex to allow reading ERR_STATUS register.
TRY(dif_rv_core_ibex_init(
Expand Down Expand Up @@ -582,6 +585,9 @@ status_t handle_rng_fi_csrng_bias_fw_override(ujson_t *uj, bool static_seed) {
}

status_t handle_rng_fi_csrng_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

pentest_select_trigger_type(kPentestTriggerTypeSw);
// As we are using the software defined trigger, the first argument of
// pentest_init is not needed. kPentestTriggerSourceAes is selected as a
Expand All @@ -590,7 +596,7 @@ status_t handle_rng_fi_csrng_init(ujson_t *uj) {
kPentestPeripheralIoDiv4 | kPentestPeripheralCsrng);

// Disable the instruction cache and dummy instructions for FI attacks.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

// Configure Ibex to allow reading ERR_STATUS register.
TRY(dif_rv_core_ibex_init(
Expand Down
5 changes: 4 additions & 1 deletion sw/device/tests/penetrationtests/firmware/fi/rom_fi.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ status_t handle_rom_read(ujson_t *uj) {
}

status_t handle_rom_fi_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

pentest_select_trigger_type(kPentestTriggerTypeSw);
pentest_init(kPentestTriggerSourceAes,
kPentestPeripheralIoDiv4 | kPentestPeripheralEdn |
Expand All @@ -86,7 +89,7 @@ status_t handle_rom_fi_init(ujson_t *uj) {
pentest_configure_alert_handler();

// Disable the instruction cache and dummy instructions for FI attacks.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

// Initialize rom_ctrl.
mmio_region_t rom_ctrl_reg =
Expand Down
16 changes: 11 additions & 5 deletions sw/device/tests/penetrationtests/firmware/lib/pentest_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,16 +308,22 @@ status_t pentest_read_device_id(uint32_t device_id[]) {
return OK_STATUS();
}

void pentest_configure_cpu(void) {
void pentest_configure_cpu(bool disable_icache, bool disable_dummy_instr) {
uint32_t cpuctrl_csr;
// Get current config.
CSR_READ(CSR_REG_CPUCTRL, &cpuctrl_csr);
// Disable the iCache.
cpuctrl_csr = bitfield_field32_write(
cpuctrl_csr, (bitfield_field32_t){.mask = 0x1, .index = 0}, 0);
if (disable_icache) {
cpuctrl_csr = bitfield_field32_write(
cpuctrl_csr, (bitfield_field32_t){.mask = 0x1, .index = 0}, 0);
}

// Disable dummy instructions.
cpuctrl_csr = bitfield_field32_write(
cpuctrl_csr, (bitfield_field32_t){.mask = 0x1, .index = 2}, 0);
if (disable_dummy_instr) {
cpuctrl_csr = bitfield_field32_write(
cpuctrl_csr, (bitfield_field32_t){.mask = 0x1, .index = 2}, 0);
}

// Write back config.
CSR_WRITE(CSR_REG_CPUCTRL, cpuctrl_csr);
}
Expand Down
17 changes: 14 additions & 3 deletions sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,21 @@ status_t pentest_read_device_id(uint32_t device_id[]);
/**
* Configures CPU for SCA and FI penetration tests.
*
* This function disables the iCache and the dummy instructions using the
* CPU Control and Status Register (cpuctrlsts).
* If disable_icache is True, this functions disables the instruction cache. If
* disable_icache is False, the instruction cache config remains at
* enabled/disabled based on the ROM configuration. This implies that the iCache
* could be disabled even though disable_icache is False.
*
* If disable_dummy_instr is True, this functions disables the dummy
* instructions. If disable_dummy_instr is False, the dummy instruction config
* remains at the original config that was set in the ROM. This implies that
* dummy instructions could disabled even though disable_dummy_instr is False.
*
* @param disable_icache Disable the instruction cache.
* @param disable_dummy_instr Disable the dummy instructions.
*
*/
void pentest_configure_cpu(void);
void pentest_configure_cpu(bool disable_icache, bool disable_dummy_instr);

/**
* Initializes the peripherals (pinmux, uart, gpio, and timer) used by SCA code.
Expand Down
7 changes: 6 additions & 1 deletion sw/device/tests/penetrationtests/firmware/sca/aes_sca.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,10 @@ status_t handle_aes_pentest_init(ujson_t *uj) {
if (uj_data.fpga_mode == 0x01) {
fpga_mode = true;
}

penetrationtest_cpuctrl_t uj_cpuctrl;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_cpuctrl));

pentest_init(kPentestTriggerSourceAes,
kPentestPeripheralIoDiv4 | kPentestPeripheralAes);

Expand All @@ -613,7 +617,8 @@ status_t handle_aes_pentest_init(ujson_t *uj) {

// Disable the instruction cache and dummy instructions for better SCA
// measurements.
pentest_configure_cpu();
pentest_configure_cpu(uj_cpuctrl.icache_disable,
uj_cpuctrl.dummy_instr_disable);

// Read device ID and return to host.
penetrationtest_device_id_t uj_output;
Expand Down
5 changes: 4 additions & 1 deletion sw/device/tests/penetrationtests/firmware/sca/edn_sca.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ status_t handle_edn_sca_bus_data(ujson_t *uj) {
}

status_t handle_edn_sca_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

pentest_select_trigger_type(kPentestTriggerTypeSw);
// As we are using the software defined trigger, the first argument of
// sca_init is not needed. kPentestTriggerSourceAes is selected as a
Expand All @@ -130,7 +133,7 @@ status_t handle_edn_sca_init(ujson_t *uj) {
kPentestPeripheralCsrng | kPentestPeripheralEdn);

// Disable the instruction cache and dummy instructions for SCA attacks.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

// Configure Ibex to allow reading ERR_STATUS register.
TRY(dif_rv_core_ibex_init(
Expand Down
5 changes: 4 additions & 1 deletion sw/device/tests/penetrationtests/firmware/sca/hmac_sca.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ static status_t trigger_hmac(uint8_t key_buf[], uint8_t mask_buf[],
}

status_t handle_hmac_pentest_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

// Setup trigger and enable peripherals needed for the test.
pentest_select_trigger_type(kPentestTriggerTypeSw);
// Enable the HMAC module and disable unused IP blocks to improve
Expand All @@ -94,7 +97,7 @@ status_t handle_hmac_pentest_init(ujson_t *uj) {
kPentestPeripheralEdn | kPentestPeripheralHmac);

// Disable the instruction cache and dummy instructions for SCA.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

// Read device ID and return to host.
penetrationtest_device_id_t uj_output;
Expand Down
5 changes: 4 additions & 1 deletion sw/device/tests/penetrationtests/firmware/sca/ibex_sca.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ static void generate_random(size_t num_iterations, uint32_t values[]) {
}

status_t handle_ibex_pentest_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

// Setup trigger and enable peripherals needed for the test.
pentest_select_trigger_type(kPentestTriggerTypeSw);
// As we are using the software defined trigger, the first argument of
Expand All @@ -122,7 +125,7 @@ status_t handle_ibex_pentest_init(ujson_t *uj) {
kPentestPeripheralIoDiv4 | kPentestPeripheralKmac);

// Disable the instruction cache and dummy instructions for SCA.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

// Key manager not initialized for the handle_ibex_sca_key_sideloading test.
key_manager_init = false;
Expand Down
7 changes: 6 additions & 1 deletion sw/device/tests/penetrationtests/firmware/sca/kmac_sca.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,10 @@ status_t handle_kmac_pentest_init(ujson_t *uj) {
if (uj_data.fpga_mode == 0x01) {
fpga_mode = true;
}

penetrationtest_cpuctrl_t uj_cpuctrl;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_cpuctrl));

// Setup the trigger.
pentest_init(kPentestTriggerSourceKmac,
kPentestPeripheralIoDiv4 | kPentestPeripheralKmac);
Expand All @@ -473,7 +477,8 @@ status_t handle_kmac_pentest_init(ujson_t *uj) {

// Disable the instruction cache and dummy instructions for better SCA
// measurements.
pentest_configure_cpu();
pentest_configure_cpu(uj_cpuctrl.icache_disable,
uj_cpuctrl.dummy_instr_disable);

// Read device ID and return to host.
penetrationtest_device_id_t uj_output;
Expand Down
5 changes: 4 additions & 1 deletion sw/device/tests/penetrationtests/firmware/sca/otbn_sca.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,9 @@ status_t handle_otbn_sca_ecdsa_p256_sign_fvsr_batch(ujson_t *uj) {
}

status_t handle_otbn_pentest_init(ujson_t *uj) {
penetrationtest_cpuctrl_t uj_data;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));

// Configure the entropy complex for OTBN. Set the reseed interval to max
// to avoid a non-constant trigger window.
TRY(pentest_configure_entropy_source_max_reseed_interval());
Expand All @@ -493,7 +496,7 @@ status_t handle_otbn_pentest_init(ujson_t *uj) {

// Disable the instruction cache and dummy instructions for better SCA
// measurements.
pentest_configure_cpu();
pentest_configure_cpu(uj_data.icache_disable, uj_data.dummy_instr_disable);

// Read device ID and return to host.
penetrationtest_device_id_t uj_output;
Expand Down
6 changes: 5 additions & 1 deletion sw/device/tests/penetrationtests/firmware/sca/sha3_sca.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,9 @@ status_t handle_sha3_pentest_init(ujson_t *uj) {
fpga_mode = true;
}

penetrationtest_cpuctrl_t uj_cpuctrl;
TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_cpuctrl));

pentest_init(kPentestTriggerSourceKmac,
kPentestPeripheralIoDiv4 | kPentestPeripheralKmac);

Expand All @@ -604,7 +607,8 @@ status_t handle_sha3_pentest_init(ujson_t *uj) {

// Disable the instruction cache and dummy instructions for better SCA
// measurements.
pentest_configure_cpu();
pentest_configure_cpu(uj_cpuctrl.icache_disable,
uj_cpuctrl.dummy_instr_disable);

// Read device ID and return to host.
penetrationtest_device_id_t uj_output;
Expand Down
5 changes: 5 additions & 0 deletions sw/device/tests/penetrationtests/json/pentest_lib_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ extern "C" {
field(device_id, uint32_t, 8)
UJSON_SERDE_STRUCT(PenetrationtestDeviceId, penetrationtest_device_id_t, PENETRATIONTEST_DEVICE_ID);

#define PENETRATIONTEST_CPUCTRL(field, string) \
field(icache_disable, bool) \
field(dummy_instr_disable, bool)
UJSON_SERDE_STRUCT(PenetrationtesCpuctrl, penetrationtest_cpuctrl_t, PENETRATIONTEST_CPUCTRL);

// clang-format on

#ifdef __cplusplus
Expand Down

0 comments on commit e4cccb7

Please sign in to comment.