diff --git a/fault_injection/configs/pen.global_fi.ibex.address_translation.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.address_translation.cw310.yaml new file mode 100644 index 000000000..6bb8d8079 --- /dev/null +++ b/fault_injection/configs/pen.global_fi.ibex.address_translation.cw310.yaml @@ -0,0 +1,44 @@ +target: + target_type: cw310 + fpga_bitstream: "../objs/lowrisc_systems_chip_earlgrey_cw310_0.1.bit" + force_program_bitstream: False + fw_bin: "../objs/sca_ujson_fpga_cw310.bin" + output_len_bytes: 16 + target_clk_mult: 0.24 + target_freq: 24000000 + baudrate: 115200 + protocol: "ujson" + port: "/dev/ttyACM4" +fisetup: + fi_gear: "husky" + fi_type: "voltage_glitch" + parameter_generation: "random" + # Voltage glitch width in cycles. + glitch_width_min: 5 + glitch_width_max: 150 + glitch_width_step: 3 + # Range for trigger delay in cycles. + trigger_delay_min: 0 + trigger_delay_max: 500 + trigger_step: 10 + # Number of iterations for the parameter sweep. + num_iterations: 100 +fiproject: + # Project database type and memory threshold. + project_db: "ot_fi_project" + project_mem_threshold: 10000 + # Store FI plot. + show_plot: True + num_plots: 10 + plot_x_axis: "trigger_delay" + plot_x_axis_legend: "[cycles]" + plot_y_axis: "glitch_width" + plot_y_axis_legend: "[cycles]" +test: + which_test: "ibex_address_translation" + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True \ No newline at end of file diff --git a/fault_injection/configs/pen.global_fi.ibex.address_translation_config.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.address_translation_config.cw310.yaml new file mode 100644 index 000000000..729ab02dc --- /dev/null +++ b/fault_injection/configs/pen.global_fi.ibex.address_translation_config.cw310.yaml @@ -0,0 +1,44 @@ +target: + target_type: cw310 + fpga_bitstream: "../objs/lowrisc_systems_chip_earlgrey_cw310_0.1.bit" + force_program_bitstream: False + fw_bin: "../objs/sca_ujson_fpga_cw310.bin" + output_len_bytes: 16 + target_clk_mult: 0.24 + target_freq: 24000000 + baudrate: 115200 + protocol: "ujson" + port: "/dev/ttyACM4" +fisetup: + fi_gear: "husky" + fi_type: "voltage_glitch" + parameter_generation: "random" + # Voltage glitch width in cycles. + glitch_width_min: 5 + glitch_width_max: 150 + glitch_width_step: 3 + # Range for trigger delay in cycles. + trigger_delay_min: 0 + trigger_delay_max: 500 + trigger_step: 10 + # Number of iterations for the parameter sweep. + num_iterations: 100 +fiproject: + # Project database type and memory threshold. + project_db: "ot_fi_project" + project_mem_threshold: 10000 + # Store FI plot. + show_plot: True + num_plots: 10 + plot_x_axis: "trigger_delay" + plot_x_axis_legend: "[cycles]" + plot_y_axis: "glitch_width" + plot_y_axis_legend: "[cycles]" +test: + which_test: "ibex_address_translation_config" + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True diff --git a/fault_injection/configs/pen.global_fi.ibex.char.conditional_branch.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.char.conditional_branch.cw310.yaml index 95c403426..1d180d997 100644 --- a/fault_injection/configs/pen.global_fi.ibex.char.conditional_branch.cw310.yaml +++ b/fault_injection/configs/pen.global_fi.ibex.char.conditional_branch.cw310.yaml @@ -36,4 +36,9 @@ fiproject: plot_y_axis_legend: "[cycles]" test: which_test: "ibex_char_conditional_branch" - expected_result: '{"result1":10001,"result2":0,"err_status":0}' + expected_result: '{"result1":10001,"result2":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True \ No newline at end of file diff --git a/fault_injection/configs/pen.global_fi.ibex.char.csr_read.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.char.csr_read.cw310.yaml new file mode 100644 index 000000000..92ccd4437 --- /dev/null +++ b/fault_injection/configs/pen.global_fi.ibex.char.csr_read.cw310.yaml @@ -0,0 +1,44 @@ +target: + target_type: cw310 + fpga_bitstream: "../objs/lowrisc_systems_chip_earlgrey_cw310_0.1.bit" + force_program_bitstream: False + fw_bin: "../objs/sca_ujson_fpga_cw310.bin" + output_len_bytes: 16 + target_clk_mult: 0.24 + target_freq: 24000000 + baudrate: 115200 + protocol: "ujson" + port: "/dev/ttyACM4" +fisetup: + fi_gear: "husky" + fi_type: "voltage_glitch" + parameter_generation: "random" + # Voltage glitch width in cycles. + glitch_width_min: 5 + glitch_width_max: 150 + glitch_width_step: 3 + # Range for trigger delay in cycles. + trigger_delay_min: 0 + trigger_delay_max: 500 + trigger_step: 10 + # Number of iterations for the parameter sweep. + num_iterations: 100 +fiproject: + # Project database type and memory threshold. + project_db: "ot_fi_project" + project_mem_threshold: 10000 + # Store FI plot. + show_plot: True + num_plots: 10 + plot_x_axis: "trigger_delay" + plot_x_axis_legend: "[cycles]" + plot_y_axis: "glitch_width" + plot_y_axis_legend: "[cycles]" +test: + which_test: "ibex_char_csr_read" + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True \ No newline at end of file diff --git a/fault_injection/configs/pen.global_fi.ibex.char.csr_write.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.char.csr_write.cw310.yaml new file mode 100644 index 000000000..fb98c1492 --- /dev/null +++ b/fault_injection/configs/pen.global_fi.ibex.char.csr_write.cw310.yaml @@ -0,0 +1,44 @@ +target: + target_type: cw310 + fpga_bitstream: "../objs/lowrisc_systems_chip_earlgrey_cw310_0.1.bit" + force_program_bitstream: False + fw_bin: "../objs/sca_ujson_fpga_cw310.bin" + output_len_bytes: 16 + target_clk_mult: 0.24 + target_freq: 24000000 + baudrate: 115200 + protocol: "ujson" + port: "/dev/ttyACM4" +fisetup: + fi_gear: "husky" + fi_type: "voltage_glitch" + parameter_generation: "random" + # Voltage glitch width in cycles. + glitch_width_min: 5 + glitch_width_max: 150 + glitch_width_step: 3 + # Range for trigger delay in cycles. + trigger_delay_min: 0 + trigger_delay_max: 500 + trigger_step: 10 + # Number of iterations for the parameter sweep. + num_iterations: 100 +fiproject: + # Project database type and memory threshold. + project_db: "ot_fi_project" + project_mem_threshold: 10000 + # Store FI plot. + show_plot: True + num_plots: 10 + plot_x_axis: "trigger_delay" + plot_x_axis_legend: "[cycles]" + plot_y_axis: "glitch_width" + plot_y_axis_legend: "[cycles]" +test: + which_test: "ibex_char_csr_write" + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True \ No newline at end of file diff --git a/fault_injection/configs/pen.global_fi.ibex.char.flash_read.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.char.flash_read.cw310.yaml index 06b8d7992..e330eaca7 100644 --- a/fault_injection/configs/pen.global_fi.ibex.char.flash_read.cw310.yaml +++ b/fault_injection/configs/pen.global_fi.ibex.char.flash_read.cw310.yaml @@ -36,4 +36,9 @@ fiproject: plot_y_axis_legend: "[cycles]" test: which_test: "ibex_char_flash_read" - expected_result: '{"result":0,"err_status":0}' + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True \ No newline at end of file diff --git a/fault_injection/configs/pen.global_fi.ibex.char.flash_write.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.char.flash_write.cw310.yaml index 09d52f9f8..7174314b8 100644 --- a/fault_injection/configs/pen.global_fi.ibex.char.flash_write.cw310.yaml +++ b/fault_injection/configs/pen.global_fi.ibex.char.flash_write.cw310.yaml @@ -36,4 +36,9 @@ fiproject: plot_y_axis_legend: "[cycles]" test: which_test: "ibex_char_flash_write" - expected_result: '{"result":0,"err_status":0}' + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True \ No newline at end of file diff --git a/fault_injection/configs/pen.global_fi.ibex.char.register_file.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.char.register_file.cw310.yaml index c1e2dff38..941cc798d 100644 --- a/fault_injection/configs/pen.global_fi.ibex.char.register_file.cw310.yaml +++ b/fault_injection/configs/pen.global_fi.ibex.char.register_file.cw310.yaml @@ -36,4 +36,9 @@ fiproject: plot_y_axis_legend: "[cycles]" test: which_test: "ibex_char_register_file" - expected_result: '{"result":0,"err_status":0}' + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True diff --git a/fault_injection/configs/pen.global_fi.ibex.char.register_file_read.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.char.register_file_read.cw310.yaml index b03bd43ea..777754473 100644 --- a/fault_injection/configs/pen.global_fi.ibex.char.register_file_read.cw310.yaml +++ b/fault_injection/configs/pen.global_fi.ibex.char.register_file_read.cw310.yaml @@ -36,4 +36,9 @@ fiproject: plot_y_axis_legend: "[cycles]" test: which_test: "ibex_char_register_file_read" - expected_result: '{"result":0,"err_status":0}' + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True diff --git a/fault_injection/configs/pen.global_fi.ibex.char.sram_read.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.char.sram_read.cw310.yaml index ed1421f2e..72a8b2425 100644 --- a/fault_injection/configs/pen.global_fi.ibex.char.sram_read.cw310.yaml +++ b/fault_injection/configs/pen.global_fi.ibex.char.sram_read.cw310.yaml @@ -36,4 +36,9 @@ fiproject: plot_y_axis_legend: "[cycles]" test: which_test: "ibex_char_sram_read" - expected_result: '{"result":0,"err_status":0}' + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True diff --git a/fault_injection/configs/pen.global_fi.ibex.char.sram_write.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.char.sram_write.cw310.yaml index e5aebd65e..d14f47345 100644 --- a/fault_injection/configs/pen.global_fi.ibex.char.sram_write.cw310.yaml +++ b/fault_injection/configs/pen.global_fi.ibex.char.sram_write.cw310.yaml @@ -36,4 +36,9 @@ fiproject: plot_y_axis_legend: "[cycles]" test: which_test: "ibex_char_sram_write" - expected_result: '{"result":0,"err_status":0}' + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True diff --git a/fault_injection/configs/pen.global_fi.ibex.char.unconditional_branch.cw310.yaml b/fault_injection/configs/pen.global_fi.ibex.char.unconditional_branch.cw310.yaml index 95fda6f7f..6ecc86a26 100644 --- a/fault_injection/configs/pen.global_fi.ibex.char.unconditional_branch.cw310.yaml +++ b/fault_injection/configs/pen.global_fi.ibex.char.unconditional_branch.cw310.yaml @@ -36,4 +36,9 @@ fiproject: plot_y_axis_legend: "[cycles]" test: which_test: "ibex_char_unconditional_branch" - expected_result: '{"result":100,"err_status":0}' + expected_result: '{"result":100,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True diff --git a/fault_injection/configs/pen.global_fi.otbn.key_sideload.cw310.yaml b/fault_injection/configs/pen.global_fi.otbn.key_sideload.cw310.yaml index 75470dc76..be95b1d19 100644 --- a/fault_injection/configs/pen.global_fi.otbn.key_sideload.cw310.yaml +++ b/fault_injection/configs/pen.global_fi.otbn.key_sideload.cw310.yaml @@ -35,4 +35,9 @@ fiproject: plot_y_axis_legend: "[cycles]" test: which_test: "otbn_key_sideload" - expected_result: '{"result":0,"err_status":0}' + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True \ No newline at end of file diff --git a/fault_injection/configs/pen.global_fi.otbn.load_integrity.cw310.yaml b/fault_injection/configs/pen.global_fi.otbn.load_integrity.cw310.yaml index 2c0af6bb7..58cce937f 100644 --- a/fault_injection/configs/pen.global_fi.otbn.load_integrity.cw310.yaml +++ b/fault_injection/configs/pen.global_fi.otbn.load_integrity.cw310.yaml @@ -35,4 +35,9 @@ fiproject: plot_y_axis_legend: "[cycles]" test: which_test: "otbn_load_integrity" - expected_result: '{"result":0,"err_status":0}' + expected_result: '{"result":0,"err_status":0,"alerts":0}' + # Set to true if the test should ignore alerts returned by the test. As the + # alert handler on the device could sometime fire alerts that are not + # related to the FI, ignoring is by default set to true. A manual analysis + # still can be performed as the alerts are stored in the database. + ignore_alerts: True \ No newline at end of file diff --git a/fault_injection/fi_ibex.py b/fault_injection/fi_ibex.py index d9558001d..4645e385e 100755 --- a/fault_injection/fi_ibex.py +++ b/fault_injection/fi_ibex.py @@ -122,28 +122,8 @@ def fi_parameter_sweep(cfg: dict, target: Target, fi_gear, response_compare = response expected_response = cfg["test"]["expected_result"] - # If the test decides to ignore alerts triggered by the alert - # handler, remove it from the received and expected response. - # In the database, the received alert is still available for - # further diagnosis. - if cfg["test"]["ignore_alerts"]: - resp_json = json.loads(response_compare) - exp_json = json.loads(expected_response) - if "alerts" in resp_json: - del resp_json["alerts"] - response_compare = json.dumps(resp_json) - if "alerts" in exp_json: - del exp_json["alerts"] - expected_response = json.dumps(exp_json) - # Compare response. - # Check if result is expected result (FI failed), unexpected result - # (FI successful), or no response (FI failed.) - fi_result = FISuccess.SUCCESS - if response_compare == expected_response: - # Expected result received. No FI effect. - fi_result = FISuccess.EXPRESPONSE - elif response == "": + if response_compare == "": # No UART response received. fi_result = FISuccess.NORESPONSE # Resetting OT as it most likely crashed. @@ -154,6 +134,29 @@ def fi_parameter_sweep(cfg: dict, target: Target, fi_gear, ot_communication.init() # Reset FIGear if necessary. fi_gear.reset() + else: + # If the test decides to ignore alerts triggered by the alert + # handler, remove it from the received and expected response. + # In the database, the received alert is still available for + # further diagnosis. + if cfg["test"]["ignore_alerts"]: + resp_json = json.loads(response_compare) + exp_json = json.loads(expected_response) + if "alerts" in resp_json: + del resp_json["alerts"] + response_compare = json.dumps(resp_json, + separators=(',', ':')) + if "alerts" in exp_json: + del exp_json["alerts"] + expected_response = json.dumps(exp_json, + separators=(',', ':')) + + # Check if result is expected result (FI failed), unexpected result + # (FI successful), or no response (FI failed.) + fi_result = FISuccess.SUCCESS + if response_compare == expected_response: + # Expected result received. No FI effect. + fi_result = FISuccess.EXPRESPONSE # Store result into FIProject. project.append_firesult( diff --git a/fault_injection/fi_otbn.py b/fault_injection/fi_otbn.py index 28ea14033..cef52854d 100755 --- a/fault_injection/fi_otbn.py +++ b/fault_injection/fi_otbn.py @@ -47,7 +47,8 @@ def setup(cfg: dict, project: Path): force_program_bitstream = cfg["target"].get("force_program_bitstream"), baudrate = cfg["target"].get("baudrate"), port = cfg["target"].get("port"), - output_len = cfg["target"].get("output_len_bytes") + output_len = cfg["target"].get("output_len_bytes"), + usb_serial = cfg["target"].get("usb_serial") ) target = Target(target_cfg) @@ -121,28 +122,8 @@ def fi_parameter_sweep(cfg: dict, target: Target, fi_gear, response_compare = response expected_response = cfg["test"]["expected_result"] - # If the test decides to ignore alerts triggered by the alert - # handler, remove it from the received and expected response. - # In the database, the received alert is still available for - # further diagnosis. - if cfg["test"]["ignore_alerts"]: - resp_json = json.loads(response_compare) - exp_json = json.loads(expected_response) - if "alerts" in resp_json: - del resp_json["alerts"] - response_compare = json.dumps(resp_json) - if "alerts" in exp_json: - del exp_json["alerts"] - expected_response = json.dumps(exp_json) - # Compare response. - # Check if result is expected result (FI failed), unexpected result - # (FI successful), or no response (FI failed.) - fi_result = FISuccess.SUCCESS - if response_compare == expected_response: - # Expected result received. No FI effect. - fi_result = FISuccess.EXPRESPONSE - elif response == "": + if response_compare == "": # No UART response received. fi_result = FISuccess.NORESPONSE # Resetting OT as it most likely crashed. @@ -155,6 +136,29 @@ def fi_parameter_sweep(cfg: dict, target: Target, fi_gear, ot_communication.init() # Reset FIGear if necessary. fi_gear.reset() + else: + # If the test decides to ignore alerts triggered by the alert + # handler, remove it from the received and expected response. + # In the database, the received alert is still available for + # further diagnosis. + if cfg["test"]["ignore_alerts"]: + resp_json = json.loads(response_compare) + exp_json = json.loads(expected_response) + if "alerts" in resp_json: + del resp_json["alerts"] + response_compare = json.dumps(resp_json, + separators=(',', ':')) + if "alerts" in exp_json: + del exp_json["alerts"] + expected_response = json.dumps(exp_json, + separators=(',', ':')) + + # Check if result is expected result (FI failed), unexpected result + # (FI successful), or no response (FI failed.) + fi_result = FISuccess.SUCCESS + if response_compare == expected_response: + # Expected result received. No FI effect. + fi_result = FISuccess.EXPRESPONSE # Store result into FIProject. project.append_firesult( diff --git a/objs/sca_ujson_fpga_cw310.bin b/objs/sca_ujson_fpga_cw310.bin old mode 100644 new mode 100755 index 8cd9d23fe..beac4491f Binary files a/objs/sca_ujson_fpga_cw310.bin and b/objs/sca_ujson_fpga_cw310.bin differ diff --git a/target/communication/fi_ibex_commands.py b/target/communication/fi_ibex_commands.py index ecb12374c..e693e06e9 100644 --- a/target/communication/fi_ibex_commands.py +++ b/target/communication/fi_ibex_commands.py @@ -149,6 +149,42 @@ def start_test(self, cfg: dict) -> None: test_function = getattr(self, cfg["test"]["which_test"]) test_function() + def ibex_char_csr_write(self) -> None: + """ Starts the ibex.fi.char.csr_write test. + """ + # IbexFi command. + self._ujson_ibex_fi_cmd() + # CharCsrWrite command. + time.sleep(0.01) + self.target.write(json.dumps("CharCsrWrite").encode("ascii")) + + def ibex_char_csr_read(self) -> None: + """ Starts the ibex.fi.char.csr_read test. + """ + # IbexFi command. + self._ujson_ibex_fi_cmd() + # CharCsrRead command. + time.sleep(0.01) + self.target.write(json.dumps("CharCsrRead").encode("ascii")) + + def ibex_address_translation_config(self) -> None: + """ Starts the ibex.fi.address_translation_config test. + """ + # IbexFi command. + self._ujson_ibex_fi_cmd() + # AddressTranslationCfg command. + time.sleep(0.01) + self.target.write(json.dumps("AddressTranslationCfg").encode("ascii")) + + def ibex_address_translation(self) -> None: + """ Starts the ibex.fi.address_translation test. + """ + # IbexFi command. + self._ujson_ibex_fi_cmd() + # AddressTranslation command. + time.sleep(0.01) + self.target.write(json.dumps("AddressTranslation").encode("ascii")) + def read_response(self, max_tries: Optional[int] = 1) -> str: """ Read response from Ibex FI framework. Args: