Skip to content

Commit

Permalink
[pentest] Batch mode for Ibex SCA
Browse files Browse the repository at this point in the history
This commit adds the following new FI and SCA ibex tests:
- ibex_sca_tl_write_batch_fvsr
- ibex_sca_tl_write_batch_fvsr_fix_address
- ibex_sca_tl_write_batch_random
- ibex_sca_tl_write_batch_random_fix_address
- ibex_sca_tl_write_fvsr
- ibex_sca_tl_write_random
- ibex_sca_tl_read_batch_fvsr
- ibex_sca_tl_read_batch_fvsr_fix_address
- ibex_sca_tl_read_batch_random
- ibex_sca_tl_read_batch_random_fix_address
- ibex_sca_tl_read_fvsr
- ibex_sca_tl_read_random
- ibex_sca_register_file_write_batch_fvsr
- ibex_sca_register_file_write_batch_random
- ibex_sca_register_file_write_fvsr
- ibex_sca_register_file_write_random
- ibex_sca_register_file_read_batch_fvsr
- ibex_sca_register_file_read_batch_random
- ibex_sca_register_file_read_fvsr
- ibex_sca_register_file_read_random
- ibex_fi_char_sram_static

The host code is located in lowRISC/ot-sca#349.

Signed-off-by: Pascal Nasahl <[email protected]>
  • Loading branch information
nasahlpa authored and timothytrippel committed Apr 10, 2024
1 parent a35cc5d commit 7f7dbbc
Show file tree
Hide file tree
Showing 9 changed files with 843 additions and 58 deletions.
2 changes: 2 additions & 0 deletions sw/device/sca/lib/prng.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ __attribute__((noinline)) static uint32_t genrand_int32(void) {

void prng_seed(uint32_t seed) { init_by_array(&seed, 1); }

uint32_t prng_rand_uint32(void) { return genrand_int32(); }

uint8_t prng_rand_byte(void) {
uint32_t rand = 0;
do {
Expand Down
10 changes: 10 additions & 0 deletions sw/device/sca/lib/prng.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ extern "C" {
*/
void prng_seed(uint32_t seed);

/**
* Generates a random uint32_t.
*
* The behavior of this function matches the behavior of `random.randint(0,
* 0xFFFFFFFF)` in python.
*
* @return A random uint32_t.
*/
uint32_t prng_rand_uint32(void);

/**
* Generates a random byte.
*
Expand Down
1 change: 1 addition & 0 deletions sw/device/tests/penetrationtests/firmware/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ cc_library(
"//sw/device/lib/testing:keymgr_testutils",
"//sw/device/lib/testing/test_framework:ujson_ottf",
"//sw/device/lib/ujson",
"//sw/device/sca/lib:prng",
"//sw/device/sca/lib:sca",
"//sw/device/tests/penetrationtests/firmware:sca_lib",
"//sw/device/tests/penetrationtests/json:ibex_sca_commands",
Expand Down
54 changes: 54 additions & 0 deletions sw/device/tests/penetrationtests/firmware/ibex_fi.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ static dif_flash_ctrl_device_info_t flash_info;
// used by the program.
OT_SECTION(".data")
static volatile uint32_t sram_main_buffer[32];
static volatile uint32_t sram_main_buffer_large[4000];

status_t handle_ibex_fi_address_translation(ujson_t *uj) {
// Clear registered alerts in alert handler.
Expand Down Expand Up @@ -471,6 +472,57 @@ status_t handle_ibex_fi_char_flash_write(ujson_t *uj) {
return OK_STATUS();
}

status_t handle_ibex_fi_char_sram_static(ujson_t *uj) {
// Clear registered alerts in alert handler.
uint32_t reg_alerts = sca_get_triggered_alerts();

// Get address of buffer located in SRAM.
uintptr_t sram_main_buffer_addr = (uintptr_t)&sram_main_buffer_large;
mmio_region_t sram_region_main_addr =
mmio_region_from_addr(sram_main_buffer_addr);

// Write reference value into SRAM.
for (int i = 0; i < 4000; i++) {
mmio_region_write32(sram_region_main_addr, i * (ptrdiff_t)sizeof(uint32_t),
ref_values[0]);
}

// FI code target.
sca_set_trigger_high();
asm volatile(NOP1000);
sca_set_trigger_low();
// Get registered alerts from alert handler.
reg_alerts = sca_get_triggered_alerts();

// Compare against reference values.
ibex_fi_faulty_addresses_t uj_output;
memset(uj_output.addresses, 0, sizeof(uj_output.addresses));
int faulty_address_pos = 0;
for (int sram_pos = 0; sram_pos < 4000; sram_pos++) {
uint32_t res_value = mmio_region_read32(
sram_region_main_addr, sram_pos * (ptrdiff_t)sizeof(uint32_t));
if (res_value != ref_values[0]) {
uj_output.addresses[faulty_address_pos] = (uint32_t)sram_pos;
faulty_address_pos++;
// Currently, we register only up to 8 faulty SRAM positions. If there
// are more, we overwrite the addresses array.
if (faulty_address_pos > 7) {
faulty_address_pos = 0;
}
}
}

// Read ERR_STATUS register.
dif_rv_core_ibex_error_status_t codes;
TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));

// Send res & ERR_STATUS to host.
uj_output.err_status = codes;
uj_output.alerts = reg_alerts;
RESP_OK(ujson_serialize_ibex_fi_faulty_addresses_t, uj, &uj_output);
return OK_STATUS(0);
}

status_t handle_ibex_fi_char_sram_read(ujson_t *uj) {
// Clear registered alerts in alert handler.
uint32_t reg_alerts = sca_get_triggered_alerts();
Expand Down Expand Up @@ -1014,6 +1066,8 @@ status_t handle_ibex_fi(ujson_t *uj) {
return handle_ibex_fi_char_sram_write(uj);
case kIbexFiSubcommandCharSramRead:
return handle_ibex_fi_char_sram_read(uj);
case kIbexFiSubcommandCharSramStatic:
return handle_ibex_fi_char_sram_static(uj);
case kIbexFiSubcommandCharFlashWrite:
return handle_ibex_fi_char_flash_write(uj);
case kIbexFiSubcommandCharFlashRead:
Expand Down
43 changes: 31 additions & 12 deletions sw/device/tests/penetrationtests/firmware/ibex_fi.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ status_t handle_ibex_fi_char_csr_write(ujson_t *uj);
status_t handle_ibex_fi_char_csr_read(ujson_t *uj);

/**
* ibex.char.flash_read command handler.
* ibex.fi.char.flash_read command handler.
*
* This FI penetration tests executes the following instructions:
* - Write reference values into flash.
Expand All @@ -112,7 +112,7 @@ status_t handle_ibex_fi_char_csr_read(ujson_t *uj);
status_t handle_ibex_fi_char_flash_read(ujson_t *uj);

/**
* ibex.char.flash_write command handler.
* ibex.fi.char.flash_write command handler.
*
* This FI penetration tests executes the following instructions:
* - Set the trigger.
Expand All @@ -131,7 +131,26 @@ status_t handle_ibex_fi_char_flash_read(ujson_t *uj);
status_t handle_ibex_fi_char_flash_write(ujson_t *uj);

/**
* ibex.char.sram_read command handler.
* ibex.fi.char.sram_static command handler.
*
* This FI penetration tests executes the following instructions:
* - Write ref_values[0] to 16kb of SRAM.
* - Set the trigger.
* - Add 1000 NOPs to give the setup the chance to inject faults.
* - Unset the trigger.
* - Read back content of 16kb of SRAM and compare against reference value.
* - If faulty words are detected, transmit addresses back to host.
*
* Faults are injected during the trigger_high & trigger_low.
* It needs to be ensured that the compiler does not optimize this code.
*
* @param uj An initialized uJSON context.
* @return OK or error.
*/
status_t handle_ibex_fi_char_sram_static(ujson_t *uj);

/**
* ibex.fi.char.sram_read command handler.
*
* This FI penetration tests executes the following instructions:
* - Write reference values into SRAM.
Expand All @@ -151,7 +170,7 @@ status_t handle_ibex_fi_char_flash_write(ujson_t *uj);
status_t handle_ibex_fi_char_sram_read(ujson_t *uj);

/**
* ibex.char.sram_write command handler.
* ibex.fi.char.sram_write command handler.
*
* This FI penetration tests executes the following instructions:
* - Set the trigger.
Expand All @@ -170,7 +189,7 @@ status_t handle_ibex_fi_char_sram_read(ujson_t *uj);
status_t handle_ibex_fi_char_sram_write(ujson_t *uj);

/**
* ibex.char.unconditional_branch command handler.
* ibex.fi.char.unconditional_branch command handler.
*
* This FI penetration tests executes the following instructions:
* - Add 10 NOPs to delay the trigger
Expand All @@ -187,7 +206,7 @@ status_t handle_ibex_fi_char_sram_write(ujson_t *uj);
status_t handle_ibex_fi_char_unconditional_branch(ujson_t *uj);

/**
* ibex.char.conditional_branch command handler.
* ibex.fi.char.conditional_branch command handler.
*
* This FI penetration tests executes the following instructions:
* - Add 10 NOPs to delay the trigger
Expand All @@ -204,7 +223,7 @@ status_t handle_ibex_fi_char_unconditional_branch(ujson_t *uj);
status_t handle_ibex_fi_char_conditional_branch(ujson_t *uj);

/**
* ibex.char.mem_op_loop command handler.
* ibex.fi.char.mem_op_loop command handler.
*
* This FI penetration tests executes the following instructions:
* - Add 100 NOPs to delay the trigger
Expand All @@ -225,7 +244,7 @@ status_t handle_ibex_fi_char_conditional_branch(ujson_t *uj);
status_t handle_ibex_fi_char_mem_op_loop(ujson_t *uj);

/**
* ibex.char.reg_op_loop command handler.
* ibex.fi.char.reg_op_loop command handler.
*
* This FI penetration tests executes the following instructions:
* - Initialize register x5=0 & x6=10000
Expand All @@ -242,7 +261,7 @@ status_t handle_ibex_fi_char_mem_op_loop(ujson_t *uj);
status_t handle_ibex_fi_char_reg_op_loop(ujson_t *uj);

/**
* ibex.char.unrolled_mem_op_loop command handler.
* ibex.fi.char.unrolled_mem_op_loop command handler.
*
* This FI penetration tests executes the following instructions:
* - Add 100 NOPs to delay the trigger
Expand All @@ -260,7 +279,7 @@ status_t handle_ibex_fi_char_reg_op_loop(ujson_t *uj);
status_t handle_ibex_fi_char_unrolled_mem_op_loop(ujson_t *uj);

/**
* ibex.char.unrolled_reg_op_loop command handler.
* ibex.fi.char.unrolled_reg_op_loop command handler.
*
* This FI penetration tests executes the following instructions:
* - Initialize register x5=0
Expand All @@ -285,7 +304,7 @@ status_t handle_ibex_fi_char_unrolled_reg_op_loop(ujson_t *uj);
status_t handle_ibex_fi_init(ujson_t *uj);

/**
* ibex.char.register_file command handler.
* ibex.fi.char.register_file command handler.
*
* This FI penetration test executes the following instructions:
* - Initialize temp. registers with reference values
Expand All @@ -301,7 +320,7 @@ status_t handle_ibex_fi_init(ujson_t *uj);
status_t handle_ibex_fi_char_register_file(ujson_t *uj);

/**
* ibex.char.register_file_read command handler.
* ibex.fi.char.register_file_read command handler.
*
* This FI penetration test executes the following instructions:
* - Initialize temp. registers with reference values
Expand Down
Loading

0 comments on commit 7f7dbbc

Please sign in to comment.