diff --git a/sw/device/tests/penetrationtests/firmware/fi/crypto_fi.c b/sw/device/tests/penetrationtests/firmware/fi/crypto_fi.c index 3f00fc83086f4..59a2328feef08 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/crypto_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/crypto_fi.c @@ -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 | @@ -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)); diff --git a/sw/device/tests/penetrationtests/firmware/fi/ibex_fi.c b/sw/device/tests/penetrationtests/firmware/fi/ibex_fi.c index 478e9a5ba955d..1dbfe5a04cfb0 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/ibex_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/ibex_fi.c @@ -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 @@ -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(); diff --git a/sw/device/tests/penetrationtests/firmware/fi/lc_ctrl_fi.c b/sw/device/tests/penetrationtests/firmware/fi/lc_ctrl_fi.c index 616437cc69cfc..d52ea58a6e213 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/lc_ctrl_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/lc_ctrl_fi.c @@ -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 @@ -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( diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c index 900a11baeba28..1519fb3897092 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c @@ -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()); @@ -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. diff --git a/sw/device/tests/penetrationtests/firmware/fi/otp_fi.c b/sw/device/tests/penetrationtests/firmware/fi/otp_fi.c index 3d4897ebfdcc4..1eddd1a106802 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otp_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/otp_fi.c @@ -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 @@ -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)); diff --git a/sw/device/tests/penetrationtests/firmware/fi/rng_fi.c b/sw/device/tests/penetrationtests/firmware/fi/rng_fi.c index bab6e684467f7..055a6750211aa 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/rng_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/rng_fi.c @@ -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 @@ -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( @@ -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 @@ -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( diff --git a/sw/device/tests/penetrationtests/firmware/fi/rom_fi.c b/sw/device/tests/penetrationtests/firmware/fi/rom_fi.c index 145ba180cdcd6..0d5c937f7276f 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/rom_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/rom_fi.c @@ -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 | @@ -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 = diff --git a/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.c b/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.c index f7c97e22a3d51..f34379174f5c8 100644 --- a/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.c +++ b/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.c @@ -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); } diff --git a/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h b/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h index 3ecc537e87327..63a8db07aeac2 100644 --- a/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h +++ b/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h @@ -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. diff --git a/sw/device/tests/penetrationtests/firmware/sca/aes_sca.c b/sw/device/tests/penetrationtests/firmware/sca/aes_sca.c index dad5bb3e3a20b..cec2772de2ea5 100644 --- a/sw/device/tests/penetrationtests/firmware/sca/aes_sca.c +++ b/sw/device/tests/penetrationtests/firmware/sca/aes_sca.c @@ -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); @@ -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; diff --git a/sw/device/tests/penetrationtests/firmware/sca/edn_sca.c b/sw/device/tests/penetrationtests/firmware/sca/edn_sca.c index 2e65686f14936..0d8589e13fab3 100644 --- a/sw/device/tests/penetrationtests/firmware/sca/edn_sca.c +++ b/sw/device/tests/penetrationtests/firmware/sca/edn_sca.c @@ -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 @@ -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( diff --git a/sw/device/tests/penetrationtests/firmware/sca/hmac_sca.c b/sw/device/tests/penetrationtests/firmware/sca/hmac_sca.c index e37a1952d57c4..74e044b81e72f 100644 --- a/sw/device/tests/penetrationtests/firmware/sca/hmac_sca.c +++ b/sw/device/tests/penetrationtests/firmware/sca/hmac_sca.c @@ -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 @@ -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; diff --git a/sw/device/tests/penetrationtests/firmware/sca/ibex_sca.c b/sw/device/tests/penetrationtests/firmware/sca/ibex_sca.c index 1f64d6ad2072c..7d47cde5d695c 100644 --- a/sw/device/tests/penetrationtests/firmware/sca/ibex_sca.c +++ b/sw/device/tests/penetrationtests/firmware/sca/ibex_sca.c @@ -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 @@ -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; diff --git a/sw/device/tests/penetrationtests/firmware/sca/kmac_sca.c b/sw/device/tests/penetrationtests/firmware/sca/kmac_sca.c index a847ec0677f4b..bdb02f44b25ef 100644 --- a/sw/device/tests/penetrationtests/firmware/sca/kmac_sca.c +++ b/sw/device/tests/penetrationtests/firmware/sca/kmac_sca.c @@ -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); @@ -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; diff --git a/sw/device/tests/penetrationtests/firmware/sca/otbn_sca.c b/sw/device/tests/penetrationtests/firmware/sca/otbn_sca.c index d52ebbbbafa9e..7732840cb8932 100644 --- a/sw/device/tests/penetrationtests/firmware/sca/otbn_sca.c +++ b/sw/device/tests/penetrationtests/firmware/sca/otbn_sca.c @@ -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()); @@ -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; diff --git a/sw/device/tests/penetrationtests/firmware/sca/sha3_sca.c b/sw/device/tests/penetrationtests/firmware/sca/sha3_sca.c index db3e84e0928d0..6100834967700 100644 --- a/sw/device/tests/penetrationtests/firmware/sca/sha3_sca.c +++ b/sw/device/tests/penetrationtests/firmware/sca/sha3_sca.c @@ -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); @@ -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; diff --git a/sw/device/tests/penetrationtests/json/pentest_lib_commands.h b/sw/device/tests/penetrationtests/json/pentest_lib_commands.h index 71bb991367f36..c6aa3d96c5382 100644 --- a/sw/device/tests/penetrationtests/json/pentest_lib_commands.h +++ b/sw/device/tests/penetrationtests/json/pentest_lib_commands.h @@ -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