From 88d2b0ad9ddd7ef77cb4cc93535df5936d4c3bf7 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Tue, 10 Dec 2024 08:05:18 +0100 Subject: [PATCH 1/9] [pentest] Add otbn.fi.char.lw test This commit adds a test that can be used to target LW instruction on OTBN with FI. Signed-off-by: Pascal Nasahl Co-authored-by: Alexander Wagner (cherry picked from commit 0b581882610f0402f888a9b6946ceb93d46f2f21) --- .../tests/penetrationtests/firmware/fi/BUILD | 1 + .../penetrationtests/firmware/fi/otbn/BUILD | 7 ++ .../firmware/fi/otbn/otbn_char_lw.s | 89 +++++++++++++++++++ .../penetrationtests/firmware/fi/otbn_fi.c | 60 +++++++++++++ .../penetrationtests/firmware/fi/otbn_fi.h | 9 ++ .../penetrationtests/json/otbn_fi_commands.h | 9 ++ 6 files changed, 175 insertions(+) create mode 100644 sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_lw.s diff --git a/sw/device/tests/penetrationtests/firmware/fi/BUILD b/sw/device/tests/penetrationtests/firmware/fi/BUILD index e7f793afad7d8..a6f973da94dff 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/BUILD @@ -93,6 +93,7 @@ cc_library( "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_hardware_dmem_op_loop", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_hardware_reg_op_loop", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_jal", + "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_lw", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_rf", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_unrolled_dmem_op_loop", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_unrolled_reg_op_loop", diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD index b21f04cb8d20a..66bfc0a7150c0 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD @@ -34,6 +34,13 @@ otbn_binary( ], ) +otbn_binary( + name = "otbn_char_lw", + srcs = [ + "otbn_char_lw.s", + ], +) + otbn_binary( name = "otbn_char_rf", srcs = [ diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_lw.s b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_lw.s new file mode 100644 index 0000000000000..3cccb39046714 --- /dev/null +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_lw.s @@ -0,0 +1,89 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + OBTN.CHAR.LW FI Penetration Test +*/ +.section .text.start + /* Load values from DMEM into a register (FI target). */ + la x31, mem_in + lw x2, 0(x31) + lw x3, 4(x31) + lw x4, 8(x31) + lw x5, 12(x31) + lw x6, 16(x31) + lw x7, 20(x31) + lw x8, 24(x31) + lw x9, 28(x31) + lw x10, 32(x31) + lw x11, 36(x31) + lw x12, 40(x31) + lw x13, 44(x31) + lw x14, 48(x31) + lw x15, 52(x31) + lw x16, 56(x31) + lw x17, 60(x31) + lw x18, 64(x31) + lw x19, 68(x31) + lw x20, 72(x31) + lw x21, 76(x31) + lw x22, 80(x31) + lw x23, 84(x31) + lw x24, 88(x31) + lw x25, 92(x31) + lw x26, 96(x31) + lw x27, 100(x31) + lw x28, 104(x31) + lw x29, 108(x31) + lw x30, 112(x31) + + /* 1000 NOPs to not accidentally hit the instructions below. */ + loopi 10, 3 + loopi 100, 1 + nop + nop + + /* Store values from registers into DMEM. */ + la x31, mem_out + sw x2, 0(x31) + sw x3, 4(x31) + sw x4, 8(x31) + sw x5, 12(x31) + sw x6, 16(x31) + sw x7, 20(x31) + sw x8, 24(x31) + sw x9, 28(x31) + sw x10, 32(x31) + sw x11, 36(x31) + sw x12, 40(x31) + sw x13, 44(x31) + sw x14, 48(x31) + sw x15, 52(x31) + sw x16, 56(x31) + sw x17, 60(x31) + sw x18, 64(x31) + sw x19, 68(x31) + sw x20, 72(x31) + sw x21, 76(x31) + sw x22, 80(x31) + sw x23, 84(x31) + sw x24, 88(x31) + sw x25, 92(x31) + sw x26, 96(x31) + sw x27, 100(x31) + sw x28, 104(x31) + sw x29, 108(x31) + sw x30, 112(x31) + + ecall + +.data + .balign 32 + .globl mem_in + mem_in: + .zero 128 + + .balign 32 + .globl mem_out + mem_out: + .zero 128 diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c index 3a57dd8a49dfa..71003caee7d10 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c @@ -340,6 +340,64 @@ status_t handle_otbn_fi_char_jal(ujson_t *uj) { return OK_STATUS(); } +status_t handle_otbn_fi_char_lw(ujson_t *uj) { + // Clear registered alerts in alert handler. + pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); + + // Initialize OTBN app, load it, and get interface to OTBN data memory. + OTBN_DECLARE_APP_SYMBOLS(otbn_char_lw); + OTBN_DECLARE_SYMBOL_ADDR(otbn_char_lw, mem_in); + OTBN_DECLARE_SYMBOL_ADDR(otbn_char_lw, mem_out); + const otbn_app_t kOtbnAppCharLw = OTBN_APP_T_INIT(otbn_char_lw); + static const otbn_addr_t kOtbnMemIn = OTBN_ADDR_T_INIT(otbn_char_lw, mem_in); + static const otbn_addr_t kOtbnMemOut = + OTBN_ADDR_T_INIT(otbn_char_lw, mem_out); + + // Load app and write reference values into mem_in DMEM. + otbn_load_app(kOtbnAppCharLw); + TRY(dif_otbn_dmem_write(&otbn, kOtbnMemIn, ref_values, sizeof(ref_values))); + + // FI code target. + pentest_set_trigger_high(); + otbn_execute(); + otbn_busy_wait_for_done(); + pentest_set_trigger_low(); + + // Get registered alerts from alert handler. + reg_alerts = pentest_get_triggered_alerts(); + + // Compare reference values. 29 values as we are loading into 29 registers. + otbn_fi_result_array_t uj_output; + uint32_t res_values[29]; + memset(res_values, 0, sizeof(res_values)); + memset(uj_output.result, 0, sizeof(uj_output.result)); + TRY(dif_otbn_dmem_read(&otbn, kOtbnMemOut, res_values, sizeof(res_values))); + for (size_t it = 0; it < 29; it++) { + uj_output.result[it] = res_values[it] ^ ref_values[it]; + } + + // Read OTBN instruction counter. + TRY(dif_otbn_get_insn_cnt(&otbn, &uj_output.insn_cnt)); + + // Read ERR_STATUS register from OTBN. + dif_otbn_err_bits_t err_otbn; + read_otbn_err_bits(&err_otbn); + + // Read ERR_STATUS register from Ibex. + dif_rv_core_ibex_error_status_t err_ibx; + TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx)); + + // Clear OTBN memory. + TRY(clear_otbn()); + + // Send back to host. + uj_output.err_otbn = err_otbn; + uj_output.err_ibx = err_ibx; + memcpy(uj_output.alerts, reg_alerts.alerts, sizeof(reg_alerts.alerts)); + RESP_OK(ujson_serialize_otbn_fi_result_array_t, uj, &uj_output); + return OK_STATUS(); +} + status_t handle_otbn_fi_char_mem(ujson_t *uj) { // Get the test mode. The test mode only can be set at the beginning of a // test. @@ -830,6 +888,8 @@ status_t handle_otbn_fi(ujson_t *uj) { return handle_otbn_fi_char_hardware_reg_op_loop(uj); case kOtbnFiSubcommandCharJal: return handle_otbn_fi_char_jal(uj); + case kOtbnFiSubcommandCharLw: + return handle_otbn_fi_char_lw(uj); case kOtbnFiSubcommandCharMem: return handle_otbn_fi_char_mem(uj); case kOtbnFiSubcommandCharRF: diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h index 4e7249d11d2d0..633234395b298 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h @@ -69,6 +69,15 @@ status_t handle_otbn_fi_char_hardware_reg_op_loop(ujson_t *uj); */ status_t handle_otbn_fi_char_jal(ujson_t *uj); +/** + * otbn.fi.char.lw command handler. + * + * The goal of this test is to manipulate LW instructions using FI. + * + * @param uj The received uJSON data. + */ +status_t handle_otbn_fi_char_lw(ujson_t *uj); + /** * otbn.fi.char_mem command handler. * diff --git a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h index 295a84c6c6ae3..6cd53dfaa1727 100644 --- a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h +++ b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h @@ -16,6 +16,7 @@ extern "C" { value(_, CharHardwareDmemOpLoop) \ value(_, CharHardwareRegOpLoop) \ value(_, CharJal) \ + value(_, CharLw) \ value(_, CharMem) \ value(_, CharRF) \ value(_, CharUnrolledDmemOpLoop) \ @@ -92,6 +93,14 @@ UJSON_SERDE_STRUCT(OtbnFiRfCharOutput, otbn_fi_rf_char_t, OTBNFI_RF_CHAR_OUTPUT) field(alerts, uint32_t, 3) UJSON_SERDE_STRUCT(OtbnFiResultCntOutput, otbn_fi_result_cnt_t, OTBNFI_RESULT_CNT_OUTPUT); +#define OTBNFI_RESULT_ARRAY(field, string) \ + field(result, uint32_t, 32) \ + field(insn_cnt, uint32_t) \ + field(err_otbn, uint32_t) \ + field(err_ibx, uint32_t) \ + field(alerts, uint32_t, 3) +UJSON_SERDE_STRUCT(OtbnFiResultArray, otbn_fi_result_array_t, OTBNFI_RESULT_ARRAY); + // clang-format on #ifdef __cplusplus From a26b2ac47a0e22ff1f76cf2e28acf52830b6a821 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Tue, 10 Dec 2024 17:49:52 +0100 Subject: [PATCH 2/9] [pentest] Add otbn.fi.char.bn_sel test This commit adds a test that allows a security evaluator to target the BN.SEL instruction of OTBN. Here, manipulating the carry flag could be one attack vector. Signed-off-by: Pascal Nasahl Co-authored-by: Alexander Wagner (cherry picked from commit 9a53fb460e13614cbacf67ec3c7fb3484147b55d) --- .../tests/penetrationtests/firmware/fi/BUILD | 1 + .../penetrationtests/firmware/fi/otbn/BUILD | 7 + .../firmware/fi/otbn/otbn_char_bn_sel.s | 1289 +++++++++++++++++ .../penetrationtests/firmware/fi/otbn_fi.c | 61 + .../penetrationtests/firmware/fi/otbn_fi.h | 13 + .../penetrationtests/json/otbn_fi_commands.h | 13 + 6 files changed, 1384 insertions(+) create mode 100644 sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_sel.s diff --git a/sw/device/tests/penetrationtests/firmware/fi/BUILD b/sw/device/tests/penetrationtests/firmware/fi/BUILD index a6f973da94dff..b92053d97c4c2 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/BUILD @@ -89,6 +89,7 @@ cc_library( "//sw/device/lib/testing:keymgr_testutils", "//sw/device/lib/testing/test_framework:ujson_ottf", "//sw/device/lib/ujson", + "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_sel", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_dmem_access", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_hardware_dmem_op_loop", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_hardware_reg_op_loop", diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD index 66bfc0a7150c0..2a83386405db8 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD @@ -6,6 +6,13 @@ load("//rules:otbn.bzl", "otbn_binary") package(default_visibility = ["//visibility:public"]) +otbn_binary( + name = "otbn_char_bn_sel", + srcs = [ + "otbn_char_bn_sel.s", + ], +) + otbn_binary( name = "otbn_char_dmem_access", srcs = [ diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_sel.s b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_sel.s new file mode 100644 index 0000000000000..425e294b0ba78 --- /dev/null +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_sel.s @@ -0,0 +1,1289 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + OBTN.CHAR_BN_SEL FI Penetration Test +*/ +.section .text.start + /* Load 2x256 bit big_num provided by host into w0 & w1. */ + la x1, big_num + li x2, 0 + li x3, 1 + bn.lid x2, 0x00(x1++) + bn.lid x3, 0x00(x1) + + /* Add with carry: big_num = big_num + big_num. */ + bn.addc w0, w0, w0 + + /* If C is set, these four instructions swap the content of w0 and w1. */ + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + /* Repeat 250 times. */ + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + bn.sel w2, w1, w0, C + bn.sel w3, w0, w1, C + bn.sel w1, w3, w2, C + bn.sel w0, w2, w3, C + + + /* Write w0 & w1 back to DEM. */ + li x2, 0 + li x3, 1 + la x1, big_num_out + bn.sid x2, 0x000(x1++) + bn.sid x3, 0x000(x1) + + ecall + +.data + .balign 32 + .globl big_num + big_num: + .zero 64 + + .globl big_num_out + .balign 32 + big_num_out: + .zero 64 diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c index 71003caee7d10..00f4e2523c938 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c @@ -150,6 +150,65 @@ status_t clear_otbn_load_checksum(void) { return OK_STATUS(); } +status_t handle_otbn_fi_char_bn_sel(ujson_t *uj) { + // Get big number (2x256 bit). + otbn_fi_big_num_t uj_data; + TRY(ujson_deserialize_otbn_fi_big_num_t(uj, &uj_data)); + + // Clear registered alerts in alert handler. + pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); + + // Initialize OTBN app, load it, and get interface to OTBN data memory. + OTBN_DECLARE_APP_SYMBOLS(otbn_char_bn_sel); + OTBN_DECLARE_SYMBOL_ADDR(otbn_char_bn_sel, big_num); + OTBN_DECLARE_SYMBOL_ADDR(otbn_char_bn_sel, big_num_out); + const otbn_app_t kOtbnAppCharBnSel = OTBN_APP_T_INIT(otbn_char_bn_sel); + static const otbn_addr_t kOtbnAppCharBnSelBigNum = + OTBN_ADDR_T_INIT(otbn_char_bn_sel, big_num); + static const otbn_addr_t kOtbnAppCharBnSelBigNumOut = + OTBN_ADDR_T_INIT(otbn_char_bn_sel, big_num_out); + + // Load app and write received big_num into DMEM. + otbn_load_app(kOtbnAppCharBnSel); + TRY(dif_otbn_dmem_write(&otbn, kOtbnAppCharBnSelBigNum, uj_data.big_num, + sizeof(uj_data.big_num))); + + // FI code target. + pentest_set_trigger_high(); + otbn_execute(); + otbn_busy_wait_for_done(); + pentest_set_trigger_low(); + // Get registered alerts from alert handler. + reg_alerts = pentest_get_triggered_alerts(); + + // Read big_num_out from OTBN data memory. + otbn_fi_big_num_out_t uj_output; + memset(uj_output.big_num, 0, sizeof(uj_output.big_num)); + TRY(dif_otbn_dmem_read(&otbn, kOtbnAppCharBnSelBigNumOut, uj_output.big_num, + sizeof(uj_output.big_num))); + + // Read OTBN instruction counter. + TRY(dif_otbn_get_insn_cnt(&otbn, &uj_output.insn_cnt)); + + // Read ERR_STATUS register from OTBN. + dif_otbn_err_bits_t err_otbn; + read_otbn_err_bits(&err_otbn); + + // Read ERR_STATUS register from Ibex. + dif_rv_core_ibex_error_status_t err_ibx; + TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx)); + + // Clear OTBN memory. + TRY(clear_otbn()); + + // Send back to host. + uj_output.err_otbn = err_otbn; + uj_output.err_ibx = err_ibx; + memcpy(uj_output.alerts, reg_alerts.alerts, sizeof(reg_alerts.alerts)); + RESP_OK(ujson_serialize_otbn_fi_big_num_out_t, uj, &uj_output); + return OK_STATUS(); +} + status_t handle_otbn_fi_char_dmem_access(ujson_t *uj) { // Clear registered alerts in alert handler. pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); @@ -880,6 +939,8 @@ status_t handle_otbn_fi(ujson_t *uj) { otbn_fi_subcommand_t cmd; TRY(ujson_deserialize_otbn_fi_subcommand_t(uj, &cmd)); switch (cmd) { + case kOtbnFiSubcommandCharBnSel: + return handle_otbn_fi_char_bn_sel(uj); case kOtbnFiSubcommandCharDmemAccess: return handle_otbn_fi_char_dmem_access(uj); case kOtbnFiSubcommandCharHardwareDmemOpLoop: diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h index 633234395b298..ed95c904b207d 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h @@ -8,6 +8,19 @@ #include "sw/device/lib/base/status.h" #include "sw/device/lib/ujson/ujson.h" +/** + * otbn.fi.char.bn_sel command handler. + * + * The goal of this test is to manipulate the carry flag or the BN.SEL + * instruction. + * + * Faults are injected during the trigger_high & trigger_low. + * It needs to be ensured that the compiler does not optimize this code. + * + * @param uj The received uJSON data. + */ +status_t handle_otbn_fi_char_bn_sel(ujson_t *uj); + /** * otbn.fi.char_dmem_access command handler. * diff --git a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h index 6cd53dfaa1727..d8b8947059d5d 100644 --- a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h +++ b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h @@ -12,6 +12,7 @@ extern "C" { // clang-format off #define OTBNFI_SUBCOMMAND(_, value) \ + value(_, CharBnSel) \ value(_, CharDmemAccess) \ value(_, CharHardwareDmemOpLoop) \ value(_, CharHardwareRegOpLoop) \ @@ -101,6 +102,18 @@ UJSON_SERDE_STRUCT(OtbnFiResultCntOutput, otbn_fi_result_cnt_t, OTBNFI_RESULT_CN field(alerts, uint32_t, 3) UJSON_SERDE_STRUCT(OtbnFiResultArray, otbn_fi_result_array_t, OTBNFI_RESULT_ARRAY); +#define OTBNFI_BIG_NUM(field, string) \ + field(big_num, uint32_t, 16) +UJSON_SERDE_STRUCT(OtbnFiBigNum, otbn_fi_big_num_t, OTBNFI_BIG_NUM); + +#define OTBNFI_BIG_NUM_OUTPUT(field, string) \ + field(big_num, uint32_t, 16) \ + field(insn_cnt, uint32_t) \ + field(err_otbn, uint32_t) \ + field(err_ibx, uint32_t) \ + field(alerts, uint32_t, 3) +UJSON_SERDE_STRUCT(OtbnFiBigNumOutput, otbn_fi_big_num_out_t, OTBNFI_BIG_NUM_OUTPUT); + // clang-format on #ifdef __cplusplus From 056465fcd062c3383e260c5e42a2a9d5116a09bf Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Tue, 10 Dec 2024 17:54:42 +0100 Subject: [PATCH 3/9] [pentest] Add otbn.fi.char.beq test This commit adds the OTBN char.beq test. In this test, the FI target is the BEQ instruction - i.e., manipulating the jump Signed-off-by: Pascal Nasahl Co-authored-by: Alexander Wagner (cherry picked from commit 3a111e2e1bd13b58dd9de95be59630d6df726a03) --- .../tests/penetrationtests/firmware/fi/BUILD | 1 + .../penetrationtests/firmware/fi/otbn/BUILD | 7 + .../firmware/fi/otbn/otbn_char_beq.s | 1527 +++++++++++++++++ .../penetrationtests/firmware/fi/otbn_fi.c | 49 + .../penetrationtests/firmware/fi/otbn_fi.h | 14 + .../penetrationtests/json/otbn_fi_commands.h | 1 + 6 files changed, 1599 insertions(+) create mode 100644 sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_beq.s diff --git a/sw/device/tests/penetrationtests/firmware/fi/BUILD b/sw/device/tests/penetrationtests/firmware/fi/BUILD index b92053d97c4c2..9158bbc2e2c2c 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/BUILD @@ -89,6 +89,7 @@ cc_library( "//sw/device/lib/testing:keymgr_testutils", "//sw/device/lib/testing/test_framework:ujson_ottf", "//sw/device/lib/ujson", + "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_beq", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_sel", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_dmem_access", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_hardware_dmem_op_loop", diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD index 2a83386405db8..e4d774db78a8e 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD @@ -6,6 +6,13 @@ load("//rules:otbn.bzl", "otbn_binary") package(default_visibility = ["//visibility:public"]) +otbn_binary( + name = "otbn_char_beq", + srcs = [ + "otbn_char_beq.s", + ], +) + otbn_binary( name = "otbn_char_bn_sel", srcs = [ diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_beq.s b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_beq.s new file mode 100644 index 0000000000000..85b5ef4d4f4ca --- /dev/null +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_beq.s @@ -0,0 +1,1527 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + OBTN.CHAR_BEQ FI Penetration Test +*/ +.section .text.start + /* x1=counter, x2&x3=BEQ parameters. */ + li x1, 0 + li x2, 0xabba + li x3, 0xabba + + /* Try to hit a BEQ instruction such that the branch is not taken. + Then, the counter at the end is different to 0. */ + beq x2, x3, label0 + addi x1, x1, 1 +label0: + beq x2, x3, label1 + addi x1, x1, 1 +label1: + beq x2, x3, label2 + addi x1, x1, 1 +label2: + beq x2, x3, label3 + addi x1, x1, 1 +label3: + beq x2, x3, label4 + addi x1, x1, 1 +label4: + beq x2, x3, label5 + addi x1, x1, 1 +label5: + beq x2, x3, label6 + addi x1, x1, 1 +label6: + beq x2, x3, label7 + addi x1, x1, 1 +label7: + beq x2, x3, label8 + addi x1, x1, 1 +label8: + beq x2, x3, label9 + addi x1, x1, 1 +label9: + beq x2, x3, label10 + addi x1, x1, 1 +label10: + beq x2, x3, label11 + addi x1, x1, 1 +label11: + beq x2, x3, label12 + addi x1, x1, 1 +label12: + beq x2, x3, label13 + addi x1, x1, 1 +label13: + beq x2, x3, label14 + addi x1, x1, 1 +label14: + beq x2, x3, label15 + addi x1, x1, 1 +label15: + beq x2, x3, label16 + addi x1, x1, 1 +label16: + beq x2, x3, label17 + addi x1, x1, 1 +label17: + beq x2, x3, label18 + addi x1, x1, 1 +label18: + beq x2, x3, label19 + addi x1, x1, 1 +label19: + beq x2, x3, label20 + addi x1, x1, 1 +label20: + beq x2, x3, label21 + addi x1, x1, 1 +label21: + beq x2, x3, label22 + addi x1, x1, 1 +label22: + beq x2, x3, label23 + addi x1, x1, 1 +label23: + beq x2, x3, label24 + addi x1, x1, 1 +label24: + beq x2, x3, label25 + addi x1, x1, 1 +label25: + beq x2, x3, label26 + addi x1, x1, 1 +label26: + beq x2, x3, label27 + addi x1, x1, 1 +label27: + beq x2, x3, label28 + addi x1, x1, 1 +label28: + beq x2, x3, label29 + addi x1, x1, 1 +label29: + beq x2, x3, label30 + addi x1, x1, 1 +label30: + beq x2, x3, label31 + addi x1, x1, 1 +label31: + beq x2, x3, label32 + addi x1, x1, 1 +label32: + beq x2, x3, label33 + addi x1, x1, 1 +label33: + beq x2, x3, label34 + addi x1, x1, 1 +label34: + beq x2, x3, label35 + addi x1, x1, 1 +label35: + beq x2, x3, label36 + addi x1, x1, 1 +label36: + beq x2, x3, label37 + addi x1, x1, 1 +label37: + beq x2, x3, label38 + addi x1, x1, 1 +label38: + beq x2, x3, label39 + addi x1, x1, 1 +label39: + beq x2, x3, label40 + addi x1, x1, 1 +label40: + beq x2, x3, label41 + addi x1, x1, 1 +label41: + beq x2, x3, label42 + addi x1, x1, 1 +label42: + beq x2, x3, label43 + addi x1, x1, 1 +label43: + beq x2, x3, label44 + addi x1, x1, 1 +label44: + beq x2, x3, label45 + addi x1, x1, 1 +label45: + beq x2, x3, label46 + addi x1, x1, 1 +label46: + beq x2, x3, label47 + addi x1, x1, 1 +label47: + beq x2, x3, label48 + addi x1, x1, 1 +label48: + beq x2, x3, label49 + addi x1, x1, 1 +label49: + beq x2, x3, label50 + addi x1, x1, 1 +label50: + beq x2, x3, label51 + addi x1, x1, 1 +label51: + beq x2, x3, label52 + addi x1, x1, 1 +label52: + beq x2, x3, label53 + addi x1, x1, 1 +label53: + beq x2, x3, label54 + addi x1, x1, 1 +label54: + beq x2, x3, label55 + addi x1, x1, 1 +label55: + beq x2, x3, label56 + addi x1, x1, 1 +label56: + beq x2, x3, label57 + addi x1, x1, 1 +label57: + beq x2, x3, label58 + addi x1, x1, 1 +label58: + beq x2, x3, label59 + addi x1, x1, 1 +label59: + beq x2, x3, label60 + addi x1, x1, 1 +label60: + beq x2, x3, label61 + addi x1, x1, 1 +label61: + beq x2, x3, label62 + addi x1, x1, 1 +label62: + beq x2, x3, label63 + addi x1, x1, 1 +label63: + beq x2, x3, label64 + addi x1, x1, 1 +label64: + beq x2, x3, label65 + addi x1, x1, 1 +label65: + beq x2, x3, label66 + addi x1, x1, 1 +label66: + beq x2, x3, label67 + addi x1, x1, 1 +label67: + beq x2, x3, label68 + addi x1, x1, 1 +label68: + beq x2, x3, label69 + addi x1, x1, 1 +label69: + beq x2, x3, label70 + addi x1, x1, 1 +label70: + beq x2, x3, label71 + addi x1, x1, 1 +label71: + beq x2, x3, label72 + addi x1, x1, 1 +label72: + beq x2, x3, label73 + addi x1, x1, 1 +label73: + beq x2, x3, label74 + addi x1, x1, 1 +label74: + beq x2, x3, label75 + addi x1, x1, 1 +label75: + beq x2, x3, label76 + addi x1, x1, 1 +label76: + beq x2, x3, label77 + addi x1, x1, 1 +label77: + beq x2, x3, label78 + addi x1, x1, 1 +label78: + beq x2, x3, label79 + addi x1, x1, 1 +label79: + beq x2, x3, label80 + addi x1, x1, 1 +label80: + beq x2, x3, label81 + addi x1, x1, 1 +label81: + beq x2, x3, label82 + addi x1, x1, 1 +label82: + beq x2, x3, label83 + addi x1, x1, 1 +label83: + beq x2, x3, label84 + addi x1, x1, 1 +label84: + beq x2, x3, label85 + addi x1, x1, 1 +label85: + beq x2, x3, label86 + addi x1, x1, 1 +label86: + beq x2, x3, label87 + addi x1, x1, 1 +label87: + beq x2, x3, label88 + addi x1, x1, 1 +label88: + beq x2, x3, label89 + addi x1, x1, 1 +label89: + beq x2, x3, label90 + addi x1, x1, 1 +label90: + beq x2, x3, label91 + addi x1, x1, 1 +label91: + beq x2, x3, label92 + addi x1, x1, 1 +label92: + beq x2, x3, label93 + addi x1, x1, 1 +label93: + beq x2, x3, label94 + addi x1, x1, 1 +label94: + beq x2, x3, label95 + addi x1, x1, 1 +label95: + beq x2, x3, label96 + addi x1, x1, 1 +label96: + beq x2, x3, label97 + addi x1, x1, 1 +label97: + beq x2, x3, label98 + addi x1, x1, 1 +label98: + beq x2, x3, label99 + addi x1, x1, 1 +label99: + beq x2, x3, label100 + addi x1, x1, 1 +label100: + beq x2, x3, label101 + addi x1, x1, 1 +label101: + beq x2, x3, label102 + addi x1, x1, 1 +label102: + beq x2, x3, label103 + addi x1, x1, 1 +label103: + beq x2, x3, label104 + addi x1, x1, 1 +label104: + beq x2, x3, label105 + addi x1, x1, 1 +label105: + beq x2, x3, label106 + addi x1, x1, 1 +label106: + beq x2, x3, label107 + addi x1, x1, 1 +label107: + beq x2, x3, label108 + addi x1, x1, 1 +label108: + beq x2, x3, label109 + addi x1, x1, 1 +label109: + beq x2, x3, label110 + addi x1, x1, 1 +label110: + beq x2, x3, label111 + addi x1, x1, 1 +label111: + beq x2, x3, label112 + addi x1, x1, 1 +label112: + beq x2, x3, label113 + addi x1, x1, 1 +label113: + beq x2, x3, label114 + addi x1, x1, 1 +label114: + beq x2, x3, label115 + addi x1, x1, 1 +label115: + beq x2, x3, label116 + addi x1, x1, 1 +label116: + beq x2, x3, label117 + addi x1, x1, 1 +label117: + beq x2, x3, label118 + addi x1, x1, 1 +label118: + beq x2, x3, label119 + addi x1, x1, 1 +label119: + beq x2, x3, label120 + addi x1, x1, 1 +label120: + beq x2, x3, label121 + addi x1, x1, 1 +label121: + beq x2, x3, label122 + addi x1, x1, 1 +label122: + beq x2, x3, label123 + addi x1, x1, 1 +label123: + beq x2, x3, label124 + addi x1, x1, 1 +label124: + beq x2, x3, label125 + addi x1, x1, 1 +label125: + beq x2, x3, label126 + addi x1, x1, 1 +label126: + beq x2, x3, label127 + addi x1, x1, 1 +label127: + beq x2, x3, label128 + addi x1, x1, 1 +label128: + beq x2, x3, label129 + addi x1, x1, 1 +label129: + beq x2, x3, label130 + addi x1, x1, 1 +label130: + beq x2, x3, label131 + addi x1, x1, 1 +label131: + beq x2, x3, label132 + addi x1, x1, 1 +label132: + beq x2, x3, label133 + addi x1, x1, 1 +label133: + beq x2, x3, label134 + addi x1, x1, 1 +label134: + beq x2, x3, label135 + addi x1, x1, 1 +label135: + beq x2, x3, label136 + addi x1, x1, 1 +label136: + beq x2, x3, label137 + addi x1, x1, 1 +label137: + beq x2, x3, label138 + addi x1, x1, 1 +label138: + beq x2, x3, label139 + addi x1, x1, 1 +label139: + beq x2, x3, label140 + addi x1, x1, 1 +label140: + beq x2, x3, label141 + addi x1, x1, 1 +label141: + beq x2, x3, label142 + addi x1, x1, 1 +label142: + beq x2, x3, label143 + addi x1, x1, 1 +label143: + beq x2, x3, label144 + addi x1, x1, 1 +label144: + beq x2, x3, label145 + addi x1, x1, 1 +label145: + beq x2, x3, label146 + addi x1, x1, 1 +label146: + beq x2, x3, label147 + addi x1, x1, 1 +label147: + beq x2, x3, label148 + addi x1, x1, 1 +label148: + beq x2, x3, label149 + addi x1, x1, 1 +label149: + beq x2, x3, label150 + addi x1, x1, 1 +label150: + beq x2, x3, label151 + addi x1, x1, 1 +label151: + beq x2, x3, label152 + addi x1, x1, 1 +label152: + beq x2, x3, label153 + addi x1, x1, 1 +label153: + beq x2, x3, label154 + addi x1, x1, 1 +label154: + beq x2, x3, label155 + addi x1, x1, 1 +label155: + beq x2, x3, label156 + addi x1, x1, 1 +label156: + beq x2, x3, label157 + addi x1, x1, 1 +label157: + beq x2, x3, label158 + addi x1, x1, 1 +label158: + beq x2, x3, label159 + addi x1, x1, 1 +label159: + beq x2, x3, label160 + addi x1, x1, 1 +label160: + beq x2, x3, label161 + addi x1, x1, 1 +label161: + beq x2, x3, label162 + addi x1, x1, 1 +label162: + beq x2, x3, label163 + addi x1, x1, 1 +label163: + beq x2, x3, label164 + addi x1, x1, 1 +label164: + beq x2, x3, label165 + addi x1, x1, 1 +label165: + beq x2, x3, label166 + addi x1, x1, 1 +label166: + beq x2, x3, label167 + addi x1, x1, 1 +label167: + beq x2, x3, label168 + addi x1, x1, 1 +label168: + beq x2, x3, label169 + addi x1, x1, 1 +label169: + beq x2, x3, label170 + addi x1, x1, 1 +label170: + beq x2, x3, label171 + addi x1, x1, 1 +label171: + beq x2, x3, label172 + addi x1, x1, 1 +label172: + beq x2, x3, label173 + addi x1, x1, 1 +label173: + beq x2, x3, label174 + addi x1, x1, 1 +label174: + beq x2, x3, label175 + addi x1, x1, 1 +label175: + beq x2, x3, label176 + addi x1, x1, 1 +label176: + beq x2, x3, label177 + addi x1, x1, 1 +label177: + beq x2, x3, label178 + addi x1, x1, 1 +label178: + beq x2, x3, label179 + addi x1, x1, 1 +label179: + beq x2, x3, label180 + addi x1, x1, 1 +label180: + beq x2, x3, label181 + addi x1, x1, 1 +label181: + beq x2, x3, label182 + addi x1, x1, 1 +label182: + beq x2, x3, label183 + addi x1, x1, 1 +label183: + beq x2, x3, label184 + addi x1, x1, 1 +label184: + beq x2, x3, label185 + addi x1, x1, 1 +label185: + beq x2, x3, label186 + addi x1, x1, 1 +label186: + beq x2, x3, label187 + addi x1, x1, 1 +label187: + beq x2, x3, label188 + addi x1, x1, 1 +label188: + beq x2, x3, label189 + addi x1, x1, 1 +label189: + beq x2, x3, label190 + addi x1, x1, 1 +label190: + beq x2, x3, label191 + addi x1, x1, 1 +label191: + beq x2, x3, label192 + addi x1, x1, 1 +label192: + beq x2, x3, label193 + addi x1, x1, 1 +label193: + beq x2, x3, label194 + addi x1, x1, 1 +label194: + beq x2, x3, label195 + addi x1, x1, 1 +label195: + beq x2, x3, label196 + addi x1, x1, 1 +label196: + beq x2, x3, label197 + addi x1, x1, 1 +label197: + beq x2, x3, label198 + addi x1, x1, 1 +label198: + beq x2, x3, label199 + addi x1, x1, 1 +label199: + beq x2, x3, label200 + addi x1, x1, 1 +label200: + beq x2, x3, label201 + addi x1, x1, 1 +label201: + beq x2, x3, label202 + addi x1, x1, 1 +label202: + beq x2, x3, label203 + addi x1, x1, 1 +label203: + beq x2, x3, label204 + addi x1, x1, 1 +label204: + beq x2, x3, label205 + addi x1, x1, 1 +label205: + beq x2, x3, label206 + addi x1, x1, 1 +label206: + beq x2, x3, label207 + addi x1, x1, 1 +label207: + beq x2, x3, label208 + addi x1, x1, 1 +label208: + beq x2, x3, label209 + addi x1, x1, 1 +label209: + beq x2, x3, label210 + addi x1, x1, 1 +label210: + beq x2, x3, label211 + addi x1, x1, 1 +label211: + beq x2, x3, label212 + addi x1, x1, 1 +label212: + beq x2, x3, label213 + addi x1, x1, 1 +label213: + beq x2, x3, label214 + addi x1, x1, 1 +label214: + beq x2, x3, label215 + addi x1, x1, 1 +label215: + beq x2, x3, label216 + addi x1, x1, 1 +label216: + beq x2, x3, label217 + addi x1, x1, 1 +label217: + beq x2, x3, label218 + addi x1, x1, 1 +label218: + beq x2, x3, label219 + addi x1, x1, 1 +label219: + beq x2, x3, label220 + addi x1, x1, 1 +label220: + beq x2, x3, label221 + addi x1, x1, 1 +label221: + beq x2, x3, label222 + addi x1, x1, 1 +label222: + beq x2, x3, label223 + addi x1, x1, 1 +label223: + beq x2, x3, label224 + addi x1, x1, 1 +label224: + beq x2, x3, label225 + addi x1, x1, 1 +label225: + beq x2, x3, label226 + addi x1, x1, 1 +label226: + beq x2, x3, label227 + addi x1, x1, 1 +label227: + beq x2, x3, label228 + addi x1, x1, 1 +label228: + beq x2, x3, label229 + addi x1, x1, 1 +label229: + beq x2, x3, label230 + addi x1, x1, 1 +label230: + beq x2, x3, label231 + addi x1, x1, 1 +label231: + beq x2, x3, label232 + addi x1, x1, 1 +label232: + beq x2, x3, label233 + addi x1, x1, 1 +label233: + beq x2, x3, label234 + addi x1, x1, 1 +label234: + beq x2, x3, label235 + addi x1, x1, 1 +label235: + beq x2, x3, label236 + addi x1, x1, 1 +label236: + beq x2, x3, label237 + addi x1, x1, 1 +label237: + beq x2, x3, label238 + addi x1, x1, 1 +label238: + beq x2, x3, label239 + addi x1, x1, 1 +label239: + beq x2, x3, label240 + addi x1, x1, 1 +label240: + beq x2, x3, label241 + addi x1, x1, 1 +label241: + beq x2, x3, label242 + addi x1, x1, 1 +label242: + beq x2, x3, label243 + addi x1, x1, 1 +label243: + beq x2, x3, label244 + addi x1, x1, 1 +label244: + beq x2, x3, label245 + addi x1, x1, 1 +label245: + beq x2, x3, label246 + addi x1, x1, 1 +label246: + beq x2, x3, label247 + addi x1, x1, 1 +label247: + beq x2, x3, label248 + addi x1, x1, 1 +label248: + beq x2, x3, label249 + addi x1, x1, 1 +label249: + beq x2, x3, label250 + addi x1, x1, 1 +label250: + beq x2, x3, label251 + addi x1, x1, 1 +label251: + beq x2, x3, label252 + addi x1, x1, 1 +label252: + beq x2, x3, label253 + addi x1, x1, 1 +label253: + beq x2, x3, label254 + addi x1, x1, 1 +label254: + beq x2, x3, label255 + addi x1, x1, 1 +label255: + beq x2, x3, label256 + addi x1, x1, 1 +label256: + beq x2, x3, label257 + addi x1, x1, 1 +label257: + beq x2, x3, label258 + addi x1, x1, 1 +label258: + beq x2, x3, label259 + addi x1, x1, 1 +label259: + beq x2, x3, label260 + addi x1, x1, 1 +label260: + beq x2, x3, label261 + addi x1, x1, 1 +label261: + beq x2, x3, label262 + addi x1, x1, 1 +label262: + beq x2, x3, label263 + addi x1, x1, 1 +label263: + beq x2, x3, label264 + addi x1, x1, 1 +label264: + beq x2, x3, label265 + addi x1, x1, 1 +label265: + beq x2, x3, label266 + addi x1, x1, 1 +label266: + beq x2, x3, label267 + addi x1, x1, 1 +label267: + beq x2, x3, label268 + addi x1, x1, 1 +label268: + beq x2, x3, label269 + addi x1, x1, 1 +label269: + beq x2, x3, label270 + addi x1, x1, 1 +label270: + beq x2, x3, label271 + addi x1, x1, 1 +label271: + beq x2, x3, label272 + addi x1, x1, 1 +label272: + beq x2, x3, label273 + addi x1, x1, 1 +label273: + beq x2, x3, label274 + addi x1, x1, 1 +label274: + beq x2, x3, label275 + addi x1, x1, 1 +label275: + beq x2, x3, label276 + addi x1, x1, 1 +label276: + beq x2, x3, label277 + addi x1, x1, 1 +label277: + beq x2, x3, label278 + addi x1, x1, 1 +label278: + beq x2, x3, label279 + addi x1, x1, 1 +label279: + beq x2, x3, label280 + addi x1, x1, 1 +label280: + beq x2, x3, label281 + addi x1, x1, 1 +label281: + beq x2, x3, label282 + addi x1, x1, 1 +label282: + beq x2, x3, label283 + addi x1, x1, 1 +label283: + beq x2, x3, label284 + addi x1, x1, 1 +label284: + beq x2, x3, label285 + addi x1, x1, 1 +label285: + beq x2, x3, label286 + addi x1, x1, 1 +label286: + beq x2, x3, label287 + addi x1, x1, 1 +label287: + beq x2, x3, label288 + addi x1, x1, 1 +label288: + beq x2, x3, label289 + addi x1, x1, 1 +label289: + beq x2, x3, label290 + addi x1, x1, 1 +label290: + beq x2, x3, label291 + addi x1, x1, 1 +label291: + beq x2, x3, label292 + addi x1, x1, 1 +label292: + beq x2, x3, label293 + addi x1, x1, 1 +label293: + beq x2, x3, label294 + addi x1, x1, 1 +label294: + beq x2, x3, label295 + addi x1, x1, 1 +label295: + beq x2, x3, label296 + addi x1, x1, 1 +label296: + beq x2, x3, label297 + addi x1, x1, 1 +label297: + beq x2, x3, label298 + addi x1, x1, 1 +label298: + beq x2, x3, label299 + addi x1, x1, 1 +label299: + beq x2, x3, label300 + addi x1, x1, 1 +label300: + beq x2, x3, label301 + addi x1, x1, 1 +label301: + beq x2, x3, label302 + addi x1, x1, 1 +label302: + beq x2, x3, label303 + addi x1, x1, 1 +label303: + beq x2, x3, label304 + addi x1, x1, 1 +label304: + beq x2, x3, label305 + addi x1, x1, 1 +label305: + beq x2, x3, label306 + addi x1, x1, 1 +label306: + beq x2, x3, label307 + addi x1, x1, 1 +label307: + beq x2, x3, label308 + addi x1, x1, 1 +label308: + beq x2, x3, label309 + addi x1, x1, 1 +label309: + beq x2, x3, label310 + addi x1, x1, 1 +label310: + beq x2, x3, label311 + addi x1, x1, 1 +label311: + beq x2, x3, label312 + addi x1, x1, 1 +label312: + beq x2, x3, label313 + addi x1, x1, 1 +label313: + beq x2, x3, label314 + addi x1, x1, 1 +label314: + beq x2, x3, label315 + addi x1, x1, 1 +label315: + beq x2, x3, label316 + addi x1, x1, 1 +label316: + beq x2, x3, label317 + addi x1, x1, 1 +label317: + beq x2, x3, label318 + addi x1, x1, 1 +label318: + beq x2, x3, label319 + addi x1, x1, 1 +label319: + beq x2, x3, label320 + addi x1, x1, 1 +label320: + beq x2, x3, label321 + addi x1, x1, 1 +label321: + beq x2, x3, label322 + addi x1, x1, 1 +label322: + beq x2, x3, label323 + addi x1, x1, 1 +label323: + beq x2, x3, label324 + addi x1, x1, 1 +label324: + beq x2, x3, label325 + addi x1, x1, 1 +label325: + beq x2, x3, label326 + addi x1, x1, 1 +label326: + beq x2, x3, label327 + addi x1, x1, 1 +label327: + beq x2, x3, label328 + addi x1, x1, 1 +label328: + beq x2, x3, label329 + addi x1, x1, 1 +label329: + beq x2, x3, label330 + addi x1, x1, 1 +label330: + beq x2, x3, label331 + addi x1, x1, 1 +label331: + beq x2, x3, label332 + addi x1, x1, 1 +label332: + beq x2, x3, label333 + addi x1, x1, 1 +label333: + beq x2, x3, label334 + addi x1, x1, 1 +label334: + beq x2, x3, label335 + addi x1, x1, 1 +label335: + beq x2, x3, label336 + addi x1, x1, 1 +label336: + beq x2, x3, label337 + addi x1, x1, 1 +label337: + beq x2, x3, label338 + addi x1, x1, 1 +label338: + beq x2, x3, label339 + addi x1, x1, 1 +label339: + beq x2, x3, label340 + addi x1, x1, 1 +label340: + beq x2, x3, label341 + addi x1, x1, 1 +label341: + beq x2, x3, label342 + addi x1, x1, 1 +label342: + beq x2, x3, label343 + addi x1, x1, 1 +label343: + beq x2, x3, label344 + addi x1, x1, 1 +label344: + beq x2, x3, label345 + addi x1, x1, 1 +label345: + beq x2, x3, label346 + addi x1, x1, 1 +label346: + beq x2, x3, label347 + addi x1, x1, 1 +label347: + beq x2, x3, label348 + addi x1, x1, 1 +label348: + beq x2, x3, label349 + addi x1, x1, 1 +label349: + beq x2, x3, label350 + addi x1, x1, 1 +label350: + beq x2, x3, label351 + addi x1, x1, 1 +label351: + beq x2, x3, label352 + addi x1, x1, 1 +label352: + beq x2, x3, label353 + addi x1, x1, 1 +label353: + beq x2, x3, label354 + addi x1, x1, 1 +label354: + beq x2, x3, label355 + addi x1, x1, 1 +label355: + beq x2, x3, label356 + addi x1, x1, 1 +label356: + beq x2, x3, label357 + addi x1, x1, 1 +label357: + beq x2, x3, label358 + addi x1, x1, 1 +label358: + beq x2, x3, label359 + addi x1, x1, 1 +label359: + beq x2, x3, label360 + addi x1, x1, 1 +label360: + beq x2, x3, label361 + addi x1, x1, 1 +label361: + beq x2, x3, label362 + addi x1, x1, 1 +label362: + beq x2, x3, label363 + addi x1, x1, 1 +label363: + beq x2, x3, label364 + addi x1, x1, 1 +label364: + beq x2, x3, label365 + addi x1, x1, 1 +label365: + beq x2, x3, label366 + addi x1, x1, 1 +label366: + beq x2, x3, label367 + addi x1, x1, 1 +label367: + beq x2, x3, label368 + addi x1, x1, 1 +label368: + beq x2, x3, label369 + addi x1, x1, 1 +label369: + beq x2, x3, label370 + addi x1, x1, 1 +label370: + beq x2, x3, label371 + addi x1, x1, 1 +label371: + beq x2, x3, label372 + addi x1, x1, 1 +label372: + beq x2, x3, label373 + addi x1, x1, 1 +label373: + beq x2, x3, label374 + addi x1, x1, 1 +label374: + beq x2, x3, label375 + addi x1, x1, 1 +label375: + beq x2, x3, label376 + addi x1, x1, 1 +label376: + beq x2, x3, label377 + addi x1, x1, 1 +label377: + beq x2, x3, label378 + addi x1, x1, 1 +label378: + beq x2, x3, label379 + addi x1, x1, 1 +label379: + beq x2, x3, label380 + addi x1, x1, 1 +label380: + beq x2, x3, label381 + addi x1, x1, 1 +label381: + beq x2, x3, label382 + addi x1, x1, 1 +label382: + beq x2, x3, label383 + addi x1, x1, 1 +label383: + beq x2, x3, label384 + addi x1, x1, 1 +label384: + beq x2, x3, label385 + addi x1, x1, 1 +label385: + beq x2, x3, label386 + addi x1, x1, 1 +label386: + beq x2, x3, label387 + addi x1, x1, 1 +label387: + beq x2, x3, label388 + addi x1, x1, 1 +label388: + beq x2, x3, label389 + addi x1, x1, 1 +label389: + beq x2, x3, label390 + addi x1, x1, 1 +label390: + beq x2, x3, label391 + addi x1, x1, 1 +label391: + beq x2, x3, label392 + addi x1, x1, 1 +label392: + beq x2, x3, label393 + addi x1, x1, 1 +label393: + beq x2, x3, label394 + addi x1, x1, 1 +label394: + beq x2, x3, label395 + addi x1, x1, 1 +label395: + beq x2, x3, label396 + addi x1, x1, 1 +label396: + beq x2, x3, label397 + addi x1, x1, 1 +label397: + beq x2, x3, label398 + addi x1, x1, 1 +label398: + beq x2, x3, label399 + addi x1, x1, 1 +label399: + beq x2, x3, label400 + addi x1, x1, 1 +label400: + beq x2, x3, label401 + addi x1, x1, 1 +label401: + beq x2, x3, label402 + addi x1, x1, 1 +label402: + beq x2, x3, label403 + addi x1, x1, 1 +label403: + beq x2, x3, label404 + addi x1, x1, 1 +label404: + beq x2, x3, label405 + addi x1, x1, 1 +label405: + beq x2, x3, label406 + addi x1, x1, 1 +label406: + beq x2, x3, label407 + addi x1, x1, 1 +label407: + beq x2, x3, label408 + addi x1, x1, 1 +label408: + beq x2, x3, label409 + addi x1, x1, 1 +label409: + beq x2, x3, label410 + addi x1, x1, 1 +label410: + beq x2, x3, label411 + addi x1, x1, 1 +label411: + beq x2, x3, label412 + addi x1, x1, 1 +label412: + beq x2, x3, label413 + addi x1, x1, 1 +label413: + beq x2, x3, label414 + addi x1, x1, 1 +label414: + beq x2, x3, label415 + addi x1, x1, 1 +label415: + beq x2, x3, label416 + addi x1, x1, 1 +label416: + beq x2, x3, label417 + addi x1, x1, 1 +label417: + beq x2, x3, label418 + addi x1, x1, 1 +label418: + beq x2, x3, label419 + addi x1, x1, 1 +label419: + beq x2, x3, label420 + addi x1, x1, 1 +label420: + beq x2, x3, label421 + addi x1, x1, 1 +label421: + beq x2, x3, label422 + addi x1, x1, 1 +label422: + beq x2, x3, label423 + addi x1, x1, 1 +label423: + beq x2, x3, label424 + addi x1, x1, 1 +label424: + beq x2, x3, label425 + addi x1, x1, 1 +label425: + beq x2, x3, label426 + addi x1, x1, 1 +label426: + beq x2, x3, label427 + addi x1, x1, 1 +label427: + beq x2, x3, label428 + addi x1, x1, 1 +label428: + beq x2, x3, label429 + addi x1, x1, 1 +label429: + beq x2, x3, label430 + addi x1, x1, 1 +label430: + beq x2, x3, label431 + addi x1, x1, 1 +label431: + beq x2, x3, label432 + addi x1, x1, 1 +label432: + beq x2, x3, label433 + addi x1, x1, 1 +label433: + beq x2, x3, label434 + addi x1, x1, 1 +label434: + beq x2, x3, label435 + addi x1, x1, 1 +label435: + beq x2, x3, label436 + addi x1, x1, 1 +label436: + beq x2, x3, label437 + addi x1, x1, 1 +label437: + beq x2, x3, label438 + addi x1, x1, 1 +label438: + beq x2, x3, label439 + addi x1, x1, 1 +label439: + beq x2, x3, label440 + addi x1, x1, 1 +label440: + beq x2, x3, label441 + addi x1, x1, 1 +label441: + beq x2, x3, label442 + addi x1, x1, 1 +label442: + beq x2, x3, label443 + addi x1, x1, 1 +label443: + beq x2, x3, label444 + addi x1, x1, 1 +label444: + beq x2, x3, label445 + addi x1, x1, 1 +label445: + beq x2, x3, label446 + addi x1, x1, 1 +label446: + beq x2, x3, label447 + addi x1, x1, 1 +label447: + beq x2, x3, label448 + addi x1, x1, 1 +label448: + beq x2, x3, label449 + addi x1, x1, 1 +label449: + beq x2, x3, label450 + addi x1, x1, 1 +label450: + beq x2, x3, label451 + addi x1, x1, 1 +label451: + beq x2, x3, label452 + addi x1, x1, 1 +label452: + beq x2, x3, label453 + addi x1, x1, 1 +label453: + beq x2, x3, label454 + addi x1, x1, 1 +label454: + beq x2, x3, label455 + addi x1, x1, 1 +label455: + beq x2, x3, label456 + addi x1, x1, 1 +label456: + beq x2, x3, label457 + addi x1, x1, 1 +label457: + beq x2, x3, label458 + addi x1, x1, 1 +label458: + beq x2, x3, label459 + addi x1, x1, 1 +label459: + beq x2, x3, label460 + addi x1, x1, 1 +label460: + beq x2, x3, label461 + addi x1, x1, 1 +label461: + beq x2, x3, label462 + addi x1, x1, 1 +label462: + beq x2, x3, label463 + addi x1, x1, 1 +label463: + beq x2, x3, label464 + addi x1, x1, 1 +label464: + beq x2, x3, label465 + addi x1, x1, 1 +label465: + beq x2, x3, label466 + addi x1, x1, 1 +label466: + beq x2, x3, label467 + addi x1, x1, 1 +label467: + beq x2, x3, label468 + addi x1, x1, 1 +label468: + beq x2, x3, label469 + addi x1, x1, 1 +label469: + beq x2, x3, label470 + addi x1, x1, 1 +label470: + beq x2, x3, label471 + addi x1, x1, 1 +label471: + beq x2, x3, label472 + addi x1, x1, 1 +label472: + beq x2, x3, label473 + addi x1, x1, 1 +label473: + beq x2, x3, label474 + addi x1, x1, 1 +label474: + beq x2, x3, label475 + addi x1, x1, 1 +label475: + beq x2, x3, label476 + addi x1, x1, 1 +label476: + beq x2, x3, label477 + addi x1, x1, 1 +label477: + beq x2, x3, label478 + addi x1, x1, 1 +label478: + beq x2, x3, label479 + addi x1, x1, 1 +label479: + beq x2, x3, label480 + addi x1, x1, 1 +label480: + beq x2, x3, label481 + addi x1, x1, 1 +label481: + beq x2, x3, label482 + addi x1, x1, 1 +label482: + beq x2, x3, label483 + addi x1, x1, 1 +label483: + beq x2, x3, label484 + addi x1, x1, 1 +label484: + beq x2, x3, label485 + addi x1, x1, 1 +label485: + beq x2, x3, label486 + addi x1, x1, 1 +label486: + beq x2, x3, label487 + addi x1, x1, 1 +label487: + beq x2, x3, label488 + addi x1, x1, 1 +label488: + beq x2, x3, label489 + addi x1, x1, 1 +label489: + beq x2, x3, label490 + addi x1, x1, 1 +label490: + beq x2, x3, label491 + addi x1, x1, 1 +label491: + beq x2, x3, label492 + addi x1, x1, 1 +label492: + beq x2, x3, label493 + addi x1, x1, 1 +label493: + beq x2, x3, label494 + addi x1, x1, 1 +label494: + beq x2, x3, label495 + addi x1, x1, 1 +label495: + beq x2, x3, label496 + addi x1, x1, 1 +label496: + beq x2, x3, label497 + addi x1, x1, 1 +label497: + beq x2, x3, label498 + addi x1, x1, 1 +label498: + beq x2, x3, label499 + addi x1, x1, 1 +label499: + + + /* Write counter into DEM. */ + la x5, res + sw x1, 0(x5) + + ecall + +.data + .balign 32 + .globl res + res: + .zero 4 diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c index 00f4e2523c938..cf6a01d338aab 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c @@ -150,6 +150,53 @@ status_t clear_otbn_load_checksum(void) { return OK_STATUS(); } +status_t handle_otbn_fi_char_beq(ujson_t *uj) { + // Clear registered alerts in alert handler. + pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); + + // Initialize OTBN app, load it, and get interface to OTBN data memory. + OTBN_DECLARE_APP_SYMBOLS(otbn_char_beq); + OTBN_DECLARE_SYMBOL_ADDR(otbn_char_beq, res); + const otbn_app_t kOtbnAppCharBeq = OTBN_APP_T_INIT(otbn_char_beq); + static const otbn_addr_t kOtbnAppCharBeqRes = + OTBN_ADDR_T_INIT(otbn_char_beq, res); + otbn_load_app(kOtbnAppCharBeq); + + // FI code target. + pentest_set_trigger_high(); + otbn_execute(); + otbn_busy_wait_for_done(); + pentest_set_trigger_low(); + // Get registered alerts from alert handler. + reg_alerts = pentest_get_triggered_alerts(); + + // Read counter (x1) from OTBN data memory. + otbn_fi_result_cnt_t uj_output; + uj_output.result = 0; + otbn_dmem_read(1, kOtbnAppCharBeqRes, &uj_output.result); + + // Read OTBN instruction counter. + TRY(dif_otbn_get_insn_cnt(&otbn, &uj_output.insn_cnt)); + + // Read ERR_STATUS register from OTBN. + dif_otbn_err_bits_t err_otbn; + read_otbn_err_bits(&err_otbn); + + // Read ERR_STATUS register from Ibex. + dif_rv_core_ibex_error_status_t err_ibx; + TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx)); + + // Clear OTBN memory. + TRY(clear_otbn()); + + // Send back to host. + uj_output.err_otbn = err_otbn; + uj_output.err_ibx = err_ibx; + memcpy(uj_output.alerts, reg_alerts.alerts, sizeof(reg_alerts.alerts)); + RESP_OK(ujson_serialize_otbn_fi_result_cnt_t, uj, &uj_output); + return OK_STATUS(); +} + status_t handle_otbn_fi_char_bn_sel(ujson_t *uj) { // Get big number (2x256 bit). otbn_fi_big_num_t uj_data; @@ -939,6 +986,8 @@ status_t handle_otbn_fi(ujson_t *uj) { otbn_fi_subcommand_t cmd; TRY(ujson_deserialize_otbn_fi_subcommand_t(uj, &cmd)); switch (cmd) { + case kOtbnFiSubcommandCharBeq: + return handle_otbn_fi_char_beq(uj); case kOtbnFiSubcommandCharBnSel: return handle_otbn_fi_char_bn_sel(uj); case kOtbnFiSubcommandCharDmemAccess: diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h index ed95c904b207d..74779428b1a9d 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h @@ -8,6 +8,20 @@ #include "sw/device/lib/base/status.h" #include "sw/device/lib/ujson/ujson.h" +/** + * otbn.fi.char.beq command handler. + * + * The goal of this test is to fault to BEQ instruction such that the jump is + * not performed. Then, a counter gets incremented. When no effective fault + * occurs, the counter is 0. + * + * Faults are injected during the trigger_high & trigger_low. + * It needs to be ensured that the compiler does not optimize this code. + * + * @param uj The received uJSON data. + */ +status_t handle_otbn_fi_char_beq(ujson_t *uj); + /** * otbn.fi.char.bn_sel command handler. * diff --git a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h index d8b8947059d5d..d02dca8afc0db 100644 --- a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h +++ b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h @@ -12,6 +12,7 @@ extern "C" { // clang-format off #define OTBNFI_SUBCOMMAND(_, value) \ + value(_, CharBeq) \ value(_, CharBnSel) \ value(_, CharDmemAccess) \ value(_, CharHardwareDmemOpLoop) \ From d05f6d10d632fa9d08e07997c403a8a51873f8c3 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Tue, 10 Dec 2024 18:00:48 +0100 Subject: [PATCH 4/9] [pentest] Add otbn.fi.char.bn_rshi test This test allows a security evaluator to characterize the big number instruction rshi. Signed-off-by: Pascal Nasahl Co-authored-by: Alexander Wagner (cherry picked from commit 1601b116f0479f2de5fbc4901e4df2dfb4c5d91f) --- .../tests/penetrationtests/firmware/fi/BUILD | 1 + .../penetrationtests/firmware/fi/otbn/BUILD | 7 + .../firmware/fi/otbn/otbn_char_bn_rshi.s | 177 ++++++++++++++++++ .../penetrationtests/firmware/fi/otbn_fi.c | 61 ++++++ .../penetrationtests/firmware/fi/otbn_fi.h | 12 ++ .../penetrationtests/json/otbn_fi_commands.h | 1 + 6 files changed, 259 insertions(+) create mode 100644 sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_rshi.s diff --git a/sw/device/tests/penetrationtests/firmware/fi/BUILD b/sw/device/tests/penetrationtests/firmware/fi/BUILD index 9158bbc2e2c2c..ce2700195b9dc 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/BUILD @@ -90,6 +90,7 @@ cc_library( "//sw/device/lib/testing/test_framework:ujson_ottf", "//sw/device/lib/ujson", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_beq", + "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_rshi", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_sel", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_dmem_access", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_hardware_dmem_op_loop", diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD index e4d774db78a8e..400233c9fe6b4 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD @@ -13,6 +13,13 @@ otbn_binary( ], ) +otbn_binary( + name = "otbn_char_bn_rshi", + srcs = [ + "otbn_char_bn_rshi.s", + ], +) + otbn_binary( name = "otbn_char_bn_sel", srcs = [ diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_rshi.s b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_rshi.s new file mode 100644 index 0000000000000..976b4ded339c8 --- /dev/null +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_rshi.s @@ -0,0 +1,177 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + OBTN.CHAR_BN_RSHI FI Penetration Test +*/ +.section .text.start + /* Load 2x256 bit big_num provided by host into w4 & w31. */ + la x1, big_num + li x2, 4 + li x3, 31 + bn.lid x2, 0x00(x1++) + bn.lid x3, 0x00(x1) + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + bn.rshi w4, w31, w4 >> 129 + bn.rshi w4, w4, w31 >> 127 + + /* Write w4 & w31 back to DEM. */ + li x2, 4 + li x3, 31 + la x1, big_num_out + bn.sid x2, 0x000(x1++) + bn.sid x3, 0x000(x1) + + ecall + +.data + .balign 32 + .globl big_num + big_num: + .zero 64 + + .globl big_num_out + .balign 32 + big_num_out: + .zero 64 diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c index cf6a01d338aab..5e7f21a476b12 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c @@ -197,6 +197,65 @@ status_t handle_otbn_fi_char_beq(ujson_t *uj) { return OK_STATUS(); } +status_t handle_otbn_fi_char_bn_rshi(ujson_t *uj) { + // Get big number (2x256 bit). + otbn_fi_big_num_t uj_data; + TRY(ujson_deserialize_otbn_fi_big_num_t(uj, &uj_data)); + + // Clear registered alerts in alert handler. + pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); + + // Initialize OTBN app, load it, and get interface to OTBN data memory. + OTBN_DECLARE_APP_SYMBOLS(otbn_char_bn_rshi); + OTBN_DECLARE_SYMBOL_ADDR(otbn_char_bn_rshi, big_num); + OTBN_DECLARE_SYMBOL_ADDR(otbn_char_bn_rshi, big_num_out); + const otbn_app_t kOtbnAppCharBnRshi = OTBN_APP_T_INIT(otbn_char_bn_rshi); + static const otbn_addr_t kOtbnAppCharBnRshiBigNum = + OTBN_ADDR_T_INIT(otbn_char_bn_rshi, big_num); + static const otbn_addr_t kOtbnAppCharBnRshiBigNumOut = + OTBN_ADDR_T_INIT(otbn_char_bn_rshi, big_num_out); + + // Load app and write received big_num into DMEM. + otbn_load_app(kOtbnAppCharBnRshi); + TRY(dif_otbn_dmem_write(&otbn, kOtbnAppCharBnRshiBigNum, uj_data.big_num, + sizeof(uj_data.big_num))); + + // FI code target. + pentest_set_trigger_high(); + otbn_execute(); + otbn_busy_wait_for_done(); + pentest_set_trigger_low(); + // Get registered alerts from alert handler. + reg_alerts = pentest_get_triggered_alerts(); + + // Read big_num_out from OTBN data memory. + otbn_fi_big_num_out_t uj_output; + memset(uj_output.big_num, 0, sizeof(uj_output.big_num)); + TRY(dif_otbn_dmem_read(&otbn, kOtbnAppCharBnRshiBigNumOut, uj_output.big_num, + sizeof(uj_output.big_num))); + + // Read OTBN instruction counter. + TRY(dif_otbn_get_insn_cnt(&otbn, &uj_output.insn_cnt)); + + // Read ERR_STATUS register from OTBN. + dif_otbn_err_bits_t err_otbn; + read_otbn_err_bits(&err_otbn); + + // Read ERR_STATUS register from Ibex. + dif_rv_core_ibex_error_status_t err_ibx; + TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx)); + + // Clear OTBN memory. + TRY(clear_otbn()); + + // Send back to host. + uj_output.err_otbn = err_otbn; + uj_output.err_ibx = err_ibx; + memcpy(uj_output.alerts, reg_alerts.alerts, sizeof(reg_alerts.alerts)); + RESP_OK(ujson_serialize_otbn_fi_big_num_out_t, uj, &uj_output); + return OK_STATUS(); +} + status_t handle_otbn_fi_char_bn_sel(ujson_t *uj) { // Get big number (2x256 bit). otbn_fi_big_num_t uj_data; @@ -988,6 +1047,8 @@ status_t handle_otbn_fi(ujson_t *uj) { switch (cmd) { case kOtbnFiSubcommandCharBeq: return handle_otbn_fi_char_beq(uj); + case kOtbnFiSubcommandCharBnRshi: + return handle_otbn_fi_char_bn_rshi(uj); case kOtbnFiSubcommandCharBnSel: return handle_otbn_fi_char_bn_sel(uj); case kOtbnFiSubcommandCharDmemAccess: diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h index 74779428b1a9d..c2a86cca34979 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h @@ -22,6 +22,18 @@ */ status_t handle_otbn_fi_char_beq(ujson_t *uj); +/** + * otbn.fi.char.bn_rshi command handler. + * + * The goal of this test is to manipulate the BN.RSHI instruction. + * + * Faults are injected during the trigger_high & trigger_low. + * It needs to be ensured that the compiler does not optimize this code. + * + * @param uj The received uJSON data. + */ +status_t handle_otbn_fi_char_bn_rshi(ujson_t *uj); + /** * otbn.fi.char.bn_sel command handler. * diff --git a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h index d02dca8afc0db..ac02506e7d331 100644 --- a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h +++ b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h @@ -13,6 +13,7 @@ extern "C" { #define OTBNFI_SUBCOMMAND(_, value) \ value(_, CharBeq) \ + value(_, CharBnRshi) \ value(_, CharBnSel) \ value(_, CharDmemAccess) \ value(_, CharHardwareDmemOpLoop) \ From dfedb8cd29b26772fcc5f500d3b972950746fb61 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Tue, 10 Dec 2024 18:09:28 +0100 Subject: [PATCH 5/9] [pentest] Add otbn.fi.char.bn_wsrr test Target the read WSR to register OTBN instruction with FI. The test returns the read registers back to the host. Signed-off-by: Pascal Nasahl Co-authored-by: Alexander Wagner (cherry picked from commit bcfed69fc07b9ac44ecedce19c94631050c86f65) --- .../tests/penetrationtests/firmware/fi/BUILD | 1 + .../penetrationtests/firmware/fi/otbn/BUILD | 7 ++ .../firmware/fi/otbn/otbn_char_bn_wsrr.s | 90 +++++++++++++++++++ .../penetrationtests/firmware/fi/otbn_fi.c | 54 +++++++++++ .../penetrationtests/firmware/fi/otbn_fi.h | 13 +++ .../penetrationtests/json/otbn_fi_commands.h | 1 + 6 files changed, 166 insertions(+) create mode 100644 sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_wsrr.s diff --git a/sw/device/tests/penetrationtests/firmware/fi/BUILD b/sw/device/tests/penetrationtests/firmware/fi/BUILD index ce2700195b9dc..80c5f641796db 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/BUILD @@ -92,6 +92,7 @@ cc_library( "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_beq", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_rshi", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_sel", + "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_wsrr", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_dmem_access", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_hardware_dmem_op_loop", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_hardware_reg_op_loop", diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD index 400233c9fe6b4..d34bee21937f3 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD @@ -27,6 +27,13 @@ otbn_binary( ], ) +otbn_binary( + name = "otbn_char_bn_wsrr", + srcs = [ + "otbn_char_bn_wsrr.s", + ], +) + otbn_binary( name = "otbn_char_dmem_access", srcs = [ diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_wsrr.s b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_wsrr.s new file mode 100644 index 0000000000000..dd4d1b83e882d --- /dev/null +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bn_wsrr.s @@ -0,0 +1,90 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + OBTN.CHAR_BN_WSRR FI Penetration Test +*/ +.section .text.start + /* Load random values into w0...w31 (FI target). */ + bn.wsrr w0, URND + bn.wsrr w1, URND + bn.wsrr w2, URND + bn.wsrr w3, URND + bn.wsrr w4, URND + bn.wsrr w5, URND + bn.wsrr w6, URND + bn.wsrr w7, URND + bn.wsrr w8, URND + bn.wsrr w9, URND + bn.wsrr w10, URND + bn.wsrr w11, URND + bn.wsrr w12, URND + bn.wsrr w13, URND + bn.wsrr w14, URND + bn.wsrr w15, URND + bn.wsrr w16, URND + bn.wsrr w17, URND + bn.wsrr w18, URND + bn.wsrr w19, URND + bn.wsrr w20, URND + bn.wsrr w21, URND + bn.wsrr w22, URND + bn.wsrr w23, URND + bn.wsrr w24, URND + bn.wsrr w25, URND + bn.wsrr w26, URND + bn.wsrr w27, URND + bn.wsrr w28, URND + bn.wsrr w29, URND + bn.wsrr w30, URND + bn.wsrr w31, URND + + /* 1000 NOPs*/ + loopi 10, 3 + loopi 100, 1 + nop + nop + + /* Read WDR RF into DMEM. */ + la x31, otbn_res_values_wdr + li x1, 0 + bn.sid x1++, 0x000(x31) + bn.sid x1++, 0x020(x31) + bn.sid x1++, 0x040(x31) + bn.sid x1++, 0x060(x31) + bn.sid x1++, 0x080(x31) + bn.sid x1++, 0x0a0(x31) + bn.sid x1++, 0x0c0(x31) + bn.sid x1++, 0x0e0(x31) + bn.sid x1++, 0x100(x31) + bn.sid x1++, 0x120(x31) + bn.sid x1++, 0x140(x31) + bn.sid x1++, 0x160(x31) + bn.sid x1++, 0x180(x31) + bn.sid x1++, 0x1a0(x31) + bn.sid x1++, 0x1c0(x31) + bn.sid x1++, 0x1e0(x31) + bn.sid x1++, 0x200(x31) + bn.sid x1++, 0x220(x31) + bn.sid x1++, 0x240(x31) + bn.sid x1++, 0x260(x31) + bn.sid x1++, 0x280(x31) + bn.sid x1++, 0x2a0(x31) + bn.sid x1++, 0x2c0(x31) + bn.sid x1++, 0x2e0(x31) + bn.sid x1++, 0x300(x31) + bn.sid x1++, 0x320(x31) + bn.sid x1++, 0x340(x31) + bn.sid x1++, 0x360(x31) + bn.sid x1++, 0x380(x31) + bn.sid x1++, 0x3a0(x31) + bn.sid x1++, 0x3c0(x31) + bn.sid x1++, 0x3e0(x31) + + ecall + +.data + .balign 32 + .globl otbn_res_values_wdr + otbn_res_values_wdr: + .zero 1024 diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c index 5e7f21a476b12..024e0377b7132 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c @@ -315,6 +315,58 @@ status_t handle_otbn_fi_char_bn_sel(ujson_t *uj) { return OK_STATUS(); } +status_t handle_otbn_fi_char_bn_wsrr(ujson_t *uj) { + // Clear registered alerts in alert handler. + pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); + + // Initialize OTBN app, load it, and get interface to OTBN data memory. + OTBN_DECLARE_APP_SYMBOLS(otbn_char_bn_wsrr); + OTBN_DECLARE_SYMBOL_ADDR(otbn_char_bn_wsrr, otbn_res_values_wdr); + const otbn_app_t kOtbnAppCharBnWsrr = OTBN_APP_T_INIT(otbn_char_bn_wsrr); + static const otbn_addr_t kOtbnAppCharBnWsrrResValuesWDR = + OTBN_ADDR_T_INIT(otbn_char_bn_wsrr, otbn_res_values_wdr); + + // Load app and write received big_num into DMEM. + otbn_load_app(kOtbnAppCharBnWsrr); + + // FI code target. + pentest_set_trigger_high(); + otbn_execute(); + otbn_busy_wait_for_done(); + pentest_set_trigger_low(); + + // Get registered alerts from alert handler. + reg_alerts = pentest_get_triggered_alerts(); + + // Read ERR_STATUS register from OTBN. + dif_otbn_err_bits_t err_otbn; + read_otbn_err_bits(&err_otbn); + + // Read ERR_STATUS register from Ibex. + dif_rv_core_ibex_error_status_t err_ibx; + TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx)); + + // Read DMEM + otbn_fi_data_t uj_output; + uj_output.res = 0; + memset(uj_output.data, 0, sizeof(uj_output.data)); + TRY(dif_otbn_dmem_read(&otbn, kOtbnAppCharBnWsrrResValuesWDR, uj_output.data, + sizeof(uj_output.data))); + // Read OTBN instruction counter + TRY(dif_otbn_get_insn_cnt(&otbn, &uj_output.insn_cnt)); + + // Clear OTBN memory. + TRY(clear_otbn()); + + // Send result & ERR_STATUS to host. + uj_output.err_otbn = err_otbn; + uj_output.err_ibx = err_ibx; + memcpy(uj_output.alerts, reg_alerts.alerts, sizeof(reg_alerts.alerts)); + RESP_OK(ujson_serialize_otbn_fi_data_t, uj, &uj_output); + + return OK_STATUS(); +} + status_t handle_otbn_fi_char_dmem_access(ujson_t *uj) { // Clear registered alerts in alert handler. pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); @@ -1051,6 +1103,8 @@ status_t handle_otbn_fi(ujson_t *uj) { return handle_otbn_fi_char_bn_rshi(uj); case kOtbnFiSubcommandCharBnSel: return handle_otbn_fi_char_bn_sel(uj); + case kOtbnFiSubcommandCharBnWsrr: + return handle_otbn_fi_char_bn_wsrr(uj); case kOtbnFiSubcommandCharDmemAccess: return handle_otbn_fi_char_dmem_access(uj); case kOtbnFiSubcommandCharHardwareDmemOpLoop: diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h index c2a86cca34979..84dffa1708516 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h @@ -47,6 +47,19 @@ status_t handle_otbn_fi_char_bn_rshi(ujson_t *uj); */ status_t handle_otbn_fi_char_bn_sel(ujson_t *uj); +/** + * otbn.fi.char.bn_wsrr command handler. + * + * The goal of this test is to manipulate the BN.WSRR instruction or the content + * of the registers. + * + * Faults are injected during the trigger_high & trigger_low. + * It needs to be ensured that the compiler does not optimize this code. + * + * @param uj The received uJSON data. + */ +status_t handle_otbn_fi_char_bn_wsrr(ujson_t *uj); + /** * otbn.fi.char_dmem_access command handler. * diff --git a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h index ac02506e7d331..ff145a2decf15 100644 --- a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h +++ b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h @@ -15,6 +15,7 @@ extern "C" { value(_, CharBeq) \ value(_, CharBnRshi) \ value(_, CharBnSel) \ + value(_, CharBnWsrr) \ value(_, CharDmemAccess) \ value(_, CharHardwareDmemOpLoop) \ value(_, CharHardwareRegOpLoop) \ From b0a1d2734bd6880e8efaad394be0375cb8cd7fd8 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Tue, 10 Dec 2024 18:29:14 +0100 Subject: [PATCH 6/9] [pentest] Add otbn.fi.char_dmem_write test This commit adds a test that can be used to check whether faults can manipulate data that is written into DMEM. Signed-off-by: Pascal Nasahl Co-authored-by: Alexander Wagner (cherry picked from commit dcdd169ac656f9af2ef8c7289e692273cc6d47b0) --- .../tests/penetrationtests/firmware/fi/BUILD | 1 + .../penetrationtests/firmware/fi/otbn/BUILD | 7 + .../firmware/fi/otbn/otbn_char_dmem_write.s | 16 ++ .../penetrationtests/firmware/fi/otbn_fi.c | 193 ++++++++++++++++++ .../penetrationtests/firmware/fi/otbn_fi.h | 11 + .../penetrationtests/json/otbn_fi_commands.h | 1 + 6 files changed, 229 insertions(+) create mode 100644 sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_dmem_write.s diff --git a/sw/device/tests/penetrationtests/firmware/fi/BUILD b/sw/device/tests/penetrationtests/firmware/fi/BUILD index 80c5f641796db..1c543e3526a77 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/BUILD @@ -94,6 +94,7 @@ cc_library( "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_sel", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_wsrr", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_dmem_access", + "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_dmem_write", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_hardware_dmem_op_loop", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_hardware_reg_op_loop", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_jal", diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD index d34bee21937f3..4ff7a80584675 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD @@ -41,6 +41,13 @@ otbn_binary( ], ) +otbn_binary( + name = "otbn_char_dmem_write", + srcs = [ + "otbn_char_dmem_write.s", + ], +) + otbn_binary( name = "otbn_char_hardware_dmem_op_loop", srcs = [ diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_dmem_write.s b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_dmem_write.s new file mode 100644 index 0000000000000..5de841e17ac12 --- /dev/null +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_dmem_write.s @@ -0,0 +1,16 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + OBTN.CHAR.DMEM_WRITE FI Penetration Test +*/ +.section .text.start + /* Just return back to Ibex as the target is the DMEM write. */ + + ecall + +.data + .balign 32 + .globl mem + mem: + .zero 128 diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c index 024e0377b7132..a86a317dd7ca8 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c @@ -82,6 +82,7 @@ uint32_t key_share_1_l_ref, key_share_1_h_ref; // NOP macros. #define NOP1 "addi x0, x0, 0\n" #define NOP10 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 +#define NOP30 NOP10 NOP10 NOP10 #define NOP100 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 // Reference values. @@ -416,6 +417,196 @@ status_t handle_otbn_fi_char_dmem_access(ujson_t *uj) { return OK_STATUS(); } +status_t handle_otbn_fi_char_dmem_write(ujson_t *uj) { + // Clear registered alerts in alert handler. + pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); + + // Config for the otbn.fi.char_rf test. + OTBN_DECLARE_APP_SYMBOLS(otbn_char_dmem_write); + OTBN_DECLARE_SYMBOL_ADDR(otbn_char_dmem_write, mem); + + static const otbn_app_t kOtbnAppCharDmemWrite = + OTBN_APP_T_INIT(otbn_char_dmem_write); + static const otbn_addr_t kOtbnVarCharDmemWriteMem = + OTBN_ADDR_T_INIT(otbn_char_dmem_write, mem); + + // Init application and load reference values into DMEM. + otbn_load_app(kOtbnAppCharDmemWrite); + // FI code target. + pentest_set_trigger_high(); + asm volatile(NOP30); + // Unrolled instruction sequence. + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem), + ref_values[0]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 4), + ref_values[1]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 8), + ref_values[2]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 12), + ref_values[3]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 16), + ref_values[4]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 20), + ref_values[5]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 24), + ref_values[6]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 28), + ref_values[7]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 32), + ref_values[8]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 36), + ref_values[9]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 40), + ref_values[10]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 44), + ref_values[11]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 48), + ref_values[12]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 52), + ref_values[13]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 56), + ref_values[14]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 60), + ref_values[15]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 64), + ref_values[16]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 68), + ref_values[17]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 72), + ref_values[18]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 76), + ref_values[19]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 80), + ref_values[20]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 84), + ref_values[21]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 88), + ref_values[22]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 92), + ref_values[23]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 96), + ref_values[24]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 100), + ref_values[25]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 104), + ref_values[26]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 108), + ref_values[27]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 112), + ref_values[28]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 116), + ref_values[29]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 120), + ref_values[30]); + mmio_region_write32( + otbn.base_addr, + (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 124), + ref_values[31]); + asm volatile(NOP10); + pentest_set_trigger_low(); + + // Execute OTBN application. + otbn_execute(); + otbn_busy_wait_for_done(); + + // Get registered alerts from alert handler. + reg_alerts = pentest_get_triggered_alerts(); + + // Read ERR_STATUS register from OTBN. + dif_otbn_err_bits_t err_otbn; + read_otbn_err_bits(&err_otbn); + + // Read ERR_STATUS register from Ibex. + dif_rv_core_ibex_error_status_t err_ibx; + TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx)); + + // Compare reference values. + otbn_fi_result_array_t uj_output; + uint32_t res_values[ARRAYSIZE(ref_values)]; + memset(res_values, 0, sizeof(res_values)); + TRY(dif_otbn_dmem_read(&otbn, kOtbnVarCharDmemWriteMem, res_values, + sizeof(res_values))); + for (size_t it = 0; it < ARRAYSIZE(ref_values); it++) { + uj_output.result[it] = res_values[it] ^ ref_values[it]; + } + + // Read OTBN instruction counter. + TRY(dif_otbn_get_insn_cnt(&otbn, &uj_output.insn_cnt)); + + // Clear OTBN memory. + TRY(clear_otbn()); + + // Send result & ERR_STATUS to host. + uj_output.err_otbn = err_otbn; + uj_output.err_ibx = err_ibx; + memcpy(uj_output.alerts, reg_alerts.alerts, sizeof(reg_alerts.alerts)); + RESP_OK(ujson_serialize_otbn_fi_result_array_t, uj, &uj_output); + + return OK_STATUS(); +} + status_t handle_otbn_fi_char_hardware_dmem_op_loop(ujson_t *uj) { // Clear registered alerts in alert handler. pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); @@ -1107,6 +1298,8 @@ status_t handle_otbn_fi(ujson_t *uj) { return handle_otbn_fi_char_bn_wsrr(uj); case kOtbnFiSubcommandCharDmemAccess: return handle_otbn_fi_char_dmem_access(uj); + case kOtbnFiSubcommandCharDmemWrite: + return handle_otbn_fi_char_dmem_write(uj); case kOtbnFiSubcommandCharHardwareDmemOpLoop: return handle_otbn_fi_char_hardware_dmem_op_loop(uj); case kOtbnFiSubcommandCharHardwareRegOpLoop: diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h index 84dffa1708516..c36b8193b6fdc 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h @@ -73,6 +73,17 @@ status_t handle_otbn_fi_char_bn_wsrr(ujson_t *uj); */ status_t handle_otbn_fi_char_dmem_access(ujson_t *uj); +/** + * otbn.fi.char_dmem_write command handler. + * + * Inject faults during Ibex writes data to DMEM. + * + * Faults are injected during the trigger_high & trigger_low. + * + * @param uj The received uJSON data. + */ +status_t handle_otbn_fi_char_dmem_write(ujson_t *uj); + /** * otbn.fi.char.hardware.dmem.op.loop command handler. * diff --git a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h index ff145a2decf15..f730a39ad60ef 100644 --- a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h +++ b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h @@ -17,6 +17,7 @@ extern "C" { value(_, CharBnSel) \ value(_, CharBnWsrr) \ value(_, CharDmemAccess) \ + value(_, CharDmemWrite) \ value(_, CharHardwareDmemOpLoop) \ value(_, CharHardwareRegOpLoop) \ value(_, CharJal) \ From a811c272c210991a40d4cfb265e905be6bced979 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Tue, 10 Dec 2024 18:34:02 +0100 Subject: [PATCH 7/9] [pentest] Add otbn.fi.pc test The goal of this test is to manipulate a program counter that is passed from Ibex to OTBN. When the PC is manipulated, the OTBN instruction counter does not match the expectation. Signed-off-by: Pascal Nasahl Co-authored-by: Alexander Wagner (cherry picked from commit d9f96a2858261b1d205dd300696c95486601a5c4) --- .../tests/penetrationtests/firmware/fi/BUILD | 1 + .../penetrationtests/firmware/fi/otbn/BUILD | 7 + .../firmware/fi/otbn/otbn_pc.s | 1048 +++++++++++++++++ .../penetrationtests/firmware/fi/otbn_fi.c | 66 ++ .../penetrationtests/firmware/fi/otbn_fi.h | 11 + .../penetrationtests/json/otbn_fi_commands.h | 16 +- 6 files changed, 1148 insertions(+), 1 deletion(-) create mode 100644 sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_pc.s diff --git a/sw/device/tests/penetrationtests/firmware/fi/BUILD b/sw/device/tests/penetrationtests/firmware/fi/BUILD index 1c543e3526a77..104611f4cb9f7 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/BUILD @@ -104,6 +104,7 @@ cc_library( "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_unrolled_reg_op_loop", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_key_sideload", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_load_integrity", + "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_pc", "//sw/device/tests/penetrationtests/firmware/lib:pentest_lib", "//sw/device/tests/penetrationtests/json:otbn_fi_commands", ], diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD index 4ff7a80584675..56a1fa2024e03 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD @@ -110,3 +110,10 @@ otbn_binary( "otbn_load_integrity.s", ], ) + +otbn_binary( + name = "otbn_pc", + srcs = [ + "otbn_pc.s", + ], +) diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_pc.s b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_pc.s new file mode 100644 index 0000000000000..0d70b59833495 --- /dev/null +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_pc.s @@ -0,0 +1,1048 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + OBTN.PC FI Penetration Test +*/ +.section .text.start + /* Load PC from DMEM. */ + la x31, pc + lw x2, 0(x31) + + /* Jump to given PC. */ + jalr x0, x2, 0 + + /* NOP slide. */ + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + /* Write back PC to DMEM. */ + la x31, pc_out + sw x2, 0(x31) + + ecall + +.data + .balign 32 + .globl pc + pc: + .zero 4 + + .balign 32 + .globl pc_out + pc_out: + .zero 4 diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c index a86a317dd7ca8..08bb9e4e68efc 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c @@ -1284,6 +1284,70 @@ status_t handle_otbn_fi_load_integrity(ujson_t *uj) { return OK_STATUS(); } +status_t handle_otbn_fi_pc(ujson_t *uj) { + // Get OTBN program counter from host. + otbn_fi_pc_t uj_data; + TRY(ujson_deserialize_otbn_fi_pc_t(uj, &uj_data)); + + // Clear registered alerts in alert handler. + pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); + + // Initialize OTBN app, load it, and get interface to OTBN data memory. + OTBN_DECLARE_APP_SYMBOLS(otbn_pc); + OTBN_DECLARE_SYMBOL_ADDR(otbn_pc, pc); + OTBN_DECLARE_SYMBOL_ADDR(otbn_pc, pc_out); + const otbn_app_t kOtbnAppPc = OTBN_APP_T_INIT(otbn_pc); + static const otbn_addr_t kOtbnPc = OTBN_ADDR_T_INIT(otbn_pc, pc); + static const otbn_addr_t kOtbnPcOut = OTBN_ADDR_T_INIT(otbn_pc, pc_out); + dif_otbn_status_t otbn_status; + + // Load app. + otbn_load_app(kOtbnAppPc); + + // FI code target. + pentest_set_trigger_high(); + TRY(dif_otbn_dmem_write(&otbn, kOtbnPc, &uj_data.pc, sizeof(uj_data.pc))); + otbn_execute(); + // Wait until is started before deasserting the trigger. + bool is_running = false; + while(!is_running) { + TRY(dif_otbn_get_status(&otbn, &otbn_status)); + if (otbn_status != kDifOtbnStatusIdle) { + is_running = true; + } + } + pentest_set_trigger_low(); + otbn_busy_wait_for_done(); + // Get registered alerts from alert handler. + reg_alerts = pentest_get_triggered_alerts(); + + // Read pc_out from OTBN data memory. + otbn_fi_pc_out_t uj_output; + TRY(dif_otbn_dmem_read(&otbn, kOtbnPcOut, &uj_output.pc_otbn, sizeof(uj_output.pc_otbn))); + TRY(dif_otbn_dmem_read(&otbn, kOtbnPc, &uj_output.pc_dmem, sizeof(uj_output.pc_dmem))); + + // Read OTBN instruction counter. + TRY(dif_otbn_get_insn_cnt(&otbn, &uj_output.insn_cnt)); + + // Read ERR_STATUS register from OTBN. + dif_otbn_err_bits_t err_otbn; + read_otbn_err_bits(&err_otbn); + + // Read ERR_STATUS register from Ibex. + dif_rv_core_ibex_error_status_t err_ibx; + TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx)); + + // Clear OTBN memory. + TRY(clear_otbn()); + + // Send back to host. + uj_output.err_otbn = err_otbn; + uj_output.err_ibx = err_ibx; + memcpy(uj_output.alerts, reg_alerts.alerts, sizeof(reg_alerts.alerts)); + RESP_OK(ujson_serialize_otbn_fi_pc_out_t, uj, &uj_output); + return OK_STATUS(); +} + status_t handle_otbn_fi(ujson_t *uj) { otbn_fi_subcommand_t cmd; TRY(ujson_deserialize_otbn_fi_subcommand_t(uj, &cmd)); @@ -1324,6 +1388,8 @@ status_t handle_otbn_fi(ujson_t *uj) { return handle_otbn_fi_key_sideload(uj); case kOtbnFiSubcommandLoadIntegrity: return handle_otbn_fi_load_integrity(uj); + case kOtbnFiSubcommandPC: + return handle_otbn_fi_pc(uj); default: LOG_ERROR("Unrecognized OTBN FI subcommand: %d", cmd); return INVALID_ARGUMENT(); diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h index c36b8193b6fdc..860d98525b418 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h @@ -249,6 +249,17 @@ status_t handle_otbn_fi_key_sideload(ujson_t *uj); */ status_t handle_otbn_fi_load_integrity(ujson_t *uj); +/** + * otbn.fi.pc command handler. + * + * The goal of this test is to fault the OTBN program counter that is passed from + * Ibex into OTBN. OTBN jumps to this PC. Manipulation can be detected by reading + * the instruction counter. + * + * @param uj The received uJSON data. + */ +status_t handle_otbn_fi_pc(ujson_t *uj); + /** * OTBN FI command handler. * diff --git a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h index f730a39ad60ef..7b575d292573d 100644 --- a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h +++ b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h @@ -29,7 +29,8 @@ extern "C" { value(_, Init) \ value(_, InitKeyMgr) \ value(_, KeySideload) \ - value(_, LoadIntegrity) + value(_, LoadIntegrity) \ + value(_, PC) UJSON_SERDE_ENUM(OtbnFiSubcommand, otbn_fi_subcommand_t, OTBNFI_SUBCOMMAND); #define OTBNFI_LOOP_COUNTER_OUTPUT(field, string) \ @@ -118,6 +119,19 @@ UJSON_SERDE_STRUCT(OtbnFiBigNum, otbn_fi_big_num_t, OTBNFI_BIG_NUM); field(alerts, uint32_t, 3) UJSON_SERDE_STRUCT(OtbnFiBigNumOutput, otbn_fi_big_num_out_t, OTBNFI_BIG_NUM_OUTPUT); +#define OTBNFI_PC(field, string) \ + field(pc, uint32_t) +UJSON_SERDE_STRUCT(OtbnFiPc, otbn_fi_pc_t, OTBNFI_PC); + +#define OTBNFI_PC_OUTPUT(field, string) \ + field(pc_dmem, uint32_t) \ + field(pc_otbn, uint32_t) \ + field(insn_cnt, uint32_t) \ + field(err_otbn, uint32_t) \ + field(err_ibx, uint32_t) \ + field(alerts, uint32_t, 3) +UJSON_SERDE_STRUCT(OtbnFiPcOutput, otbn_fi_pc_out_t, OTBNFI_PC_OUTPUT); + // clang-format on #ifdef __cplusplus From dd0464c7c8fe26cb1f9d7f07c1c89e58e5501aca Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Tue, 10 Dec 2024 18:46:39 +0100 Subject: [PATCH 8/9] [pentest] Add otbn.fi.char.bne test The goal of this test is to fault to BNE instruction such that the jump is not performed. Signed-off-by: Pascal Nasahl Co-authored-by: Alexander Wagner (cherry picked from commit 10025ff6dfd142ea6ed15a09650e7a160e55990d) --- .../tests/penetrationtests/firmware/fi/BUILD | 1 + .../penetrationtests/firmware/fi/otbn/BUILD | 7 + .../firmware/fi/otbn/otbn_char_bne.s | 1527 +++++++++++++++++ .../penetrationtests/firmware/fi/otbn_fi.c | 58 +- .../penetrationtests/firmware/fi/otbn_fi.h | 20 +- .../penetrationtests/json/otbn_fi_commands.h | 1 + 6 files changed, 1607 insertions(+), 7 deletions(-) create mode 100644 sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bne.s diff --git a/sw/device/tests/penetrationtests/firmware/fi/BUILD b/sw/device/tests/penetrationtests/firmware/fi/BUILD index 104611f4cb9f7..2e25e44b12a6a 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/BUILD @@ -93,6 +93,7 @@ cc_library( "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_rshi", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_sel", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bn_wsrr", + "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_bne", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_dmem_access", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_dmem_write", "//sw/device/tests/penetrationtests/firmware/fi/otbn:otbn_char_hardware_dmem_op_loop", diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD index 56a1fa2024e03..846c290c44941 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/BUILD @@ -34,6 +34,13 @@ otbn_binary( ], ) +otbn_binary( + name = "otbn_char_bne", + srcs = [ + "otbn_char_bne.s", + ], +) + otbn_binary( name = "otbn_char_dmem_access", srcs = [ diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bne.s b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bne.s new file mode 100644 index 0000000000000..c1fbc30a0c128 --- /dev/null +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn/otbn_char_bne.s @@ -0,0 +1,1527 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + OBTN.CHAR_BNE FI Penetration Test +*/ +.section .text.start + /* x1=counter, x2&x3=BNE parameters. */ + li x1, 0 + li x2, 0xabba + li x3, 0xcafe + + /* Try to hit a BNE instruction such that the branch is not taken. + Then, the counter at the end is different to 0. */ + bne x2, x3, label0 + addi x1, x1, 1 +label0: + bne x2, x3, label1 + addi x1, x1, 1 +label1: + bne x2, x3, label2 + addi x1, x1, 1 +label2: + bne x2, x3, label3 + addi x1, x1, 1 +label3: + bne x2, x3, label4 + addi x1, x1, 1 +label4: + bne x2, x3, label5 + addi x1, x1, 1 +label5: + bne x2, x3, label6 + addi x1, x1, 1 +label6: + bne x2, x3, label7 + addi x1, x1, 1 +label7: + bne x2, x3, label8 + addi x1, x1, 1 +label8: + bne x2, x3, label9 + addi x1, x1, 1 +label9: + bne x2, x3, label10 + addi x1, x1, 1 +label10: + bne x2, x3, label11 + addi x1, x1, 1 +label11: + bne x2, x3, label12 + addi x1, x1, 1 +label12: + bne x2, x3, label13 + addi x1, x1, 1 +label13: + bne x2, x3, label14 + addi x1, x1, 1 +label14: + bne x2, x3, label15 + addi x1, x1, 1 +label15: + bne x2, x3, label16 + addi x1, x1, 1 +label16: + bne x2, x3, label17 + addi x1, x1, 1 +label17: + bne x2, x3, label18 + addi x1, x1, 1 +label18: + bne x2, x3, label19 + addi x1, x1, 1 +label19: + bne x2, x3, label20 + addi x1, x1, 1 +label20: + bne x2, x3, label21 + addi x1, x1, 1 +label21: + bne x2, x3, label22 + addi x1, x1, 1 +label22: + bne x2, x3, label23 + addi x1, x1, 1 +label23: + bne x2, x3, label24 + addi x1, x1, 1 +label24: + bne x2, x3, label25 + addi x1, x1, 1 +label25: + bne x2, x3, label26 + addi x1, x1, 1 +label26: + bne x2, x3, label27 + addi x1, x1, 1 +label27: + bne x2, x3, label28 + addi x1, x1, 1 +label28: + bne x2, x3, label29 + addi x1, x1, 1 +label29: + bne x2, x3, label30 + addi x1, x1, 1 +label30: + bne x2, x3, label31 + addi x1, x1, 1 +label31: + bne x2, x3, label32 + addi x1, x1, 1 +label32: + bne x2, x3, label33 + addi x1, x1, 1 +label33: + bne x2, x3, label34 + addi x1, x1, 1 +label34: + bne x2, x3, label35 + addi x1, x1, 1 +label35: + bne x2, x3, label36 + addi x1, x1, 1 +label36: + bne x2, x3, label37 + addi x1, x1, 1 +label37: + bne x2, x3, label38 + addi x1, x1, 1 +label38: + bne x2, x3, label39 + addi x1, x1, 1 +label39: + bne x2, x3, label40 + addi x1, x1, 1 +label40: + bne x2, x3, label41 + addi x1, x1, 1 +label41: + bne x2, x3, label42 + addi x1, x1, 1 +label42: + bne x2, x3, label43 + addi x1, x1, 1 +label43: + bne x2, x3, label44 + addi x1, x1, 1 +label44: + bne x2, x3, label45 + addi x1, x1, 1 +label45: + bne x2, x3, label46 + addi x1, x1, 1 +label46: + bne x2, x3, label47 + addi x1, x1, 1 +label47: + bne x2, x3, label48 + addi x1, x1, 1 +label48: + bne x2, x3, label49 + addi x1, x1, 1 +label49: + bne x2, x3, label50 + addi x1, x1, 1 +label50: + bne x2, x3, label51 + addi x1, x1, 1 +label51: + bne x2, x3, label52 + addi x1, x1, 1 +label52: + bne x2, x3, label53 + addi x1, x1, 1 +label53: + bne x2, x3, label54 + addi x1, x1, 1 +label54: + bne x2, x3, label55 + addi x1, x1, 1 +label55: + bne x2, x3, label56 + addi x1, x1, 1 +label56: + bne x2, x3, label57 + addi x1, x1, 1 +label57: + bne x2, x3, label58 + addi x1, x1, 1 +label58: + bne x2, x3, label59 + addi x1, x1, 1 +label59: + bne x2, x3, label60 + addi x1, x1, 1 +label60: + bne x2, x3, label61 + addi x1, x1, 1 +label61: + bne x2, x3, label62 + addi x1, x1, 1 +label62: + bne x2, x3, label63 + addi x1, x1, 1 +label63: + bne x2, x3, label64 + addi x1, x1, 1 +label64: + bne x2, x3, label65 + addi x1, x1, 1 +label65: + bne x2, x3, label66 + addi x1, x1, 1 +label66: + bne x2, x3, label67 + addi x1, x1, 1 +label67: + bne x2, x3, label68 + addi x1, x1, 1 +label68: + bne x2, x3, label69 + addi x1, x1, 1 +label69: + bne x2, x3, label70 + addi x1, x1, 1 +label70: + bne x2, x3, label71 + addi x1, x1, 1 +label71: + bne x2, x3, label72 + addi x1, x1, 1 +label72: + bne x2, x3, label73 + addi x1, x1, 1 +label73: + bne x2, x3, label74 + addi x1, x1, 1 +label74: + bne x2, x3, label75 + addi x1, x1, 1 +label75: + bne x2, x3, label76 + addi x1, x1, 1 +label76: + bne x2, x3, label77 + addi x1, x1, 1 +label77: + bne x2, x3, label78 + addi x1, x1, 1 +label78: + bne x2, x3, label79 + addi x1, x1, 1 +label79: + bne x2, x3, label80 + addi x1, x1, 1 +label80: + bne x2, x3, label81 + addi x1, x1, 1 +label81: + bne x2, x3, label82 + addi x1, x1, 1 +label82: + bne x2, x3, label83 + addi x1, x1, 1 +label83: + bne x2, x3, label84 + addi x1, x1, 1 +label84: + bne x2, x3, label85 + addi x1, x1, 1 +label85: + bne x2, x3, label86 + addi x1, x1, 1 +label86: + bne x2, x3, label87 + addi x1, x1, 1 +label87: + bne x2, x3, label88 + addi x1, x1, 1 +label88: + bne x2, x3, label89 + addi x1, x1, 1 +label89: + bne x2, x3, label90 + addi x1, x1, 1 +label90: + bne x2, x3, label91 + addi x1, x1, 1 +label91: + bne x2, x3, label92 + addi x1, x1, 1 +label92: + bne x2, x3, label93 + addi x1, x1, 1 +label93: + bne x2, x3, label94 + addi x1, x1, 1 +label94: + bne x2, x3, label95 + addi x1, x1, 1 +label95: + bne x2, x3, label96 + addi x1, x1, 1 +label96: + bne x2, x3, label97 + addi x1, x1, 1 +label97: + bne x2, x3, label98 + addi x1, x1, 1 +label98: + bne x2, x3, label99 + addi x1, x1, 1 +label99: + bne x2, x3, label100 + addi x1, x1, 1 +label100: + bne x2, x3, label101 + addi x1, x1, 1 +label101: + bne x2, x3, label102 + addi x1, x1, 1 +label102: + bne x2, x3, label103 + addi x1, x1, 1 +label103: + bne x2, x3, label104 + addi x1, x1, 1 +label104: + bne x2, x3, label105 + addi x1, x1, 1 +label105: + bne x2, x3, label106 + addi x1, x1, 1 +label106: + bne x2, x3, label107 + addi x1, x1, 1 +label107: + bne x2, x3, label108 + addi x1, x1, 1 +label108: + bne x2, x3, label109 + addi x1, x1, 1 +label109: + bne x2, x3, label110 + addi x1, x1, 1 +label110: + bne x2, x3, label111 + addi x1, x1, 1 +label111: + bne x2, x3, label112 + addi x1, x1, 1 +label112: + bne x2, x3, label113 + addi x1, x1, 1 +label113: + bne x2, x3, label114 + addi x1, x1, 1 +label114: + bne x2, x3, label115 + addi x1, x1, 1 +label115: + bne x2, x3, label116 + addi x1, x1, 1 +label116: + bne x2, x3, label117 + addi x1, x1, 1 +label117: + bne x2, x3, label118 + addi x1, x1, 1 +label118: + bne x2, x3, label119 + addi x1, x1, 1 +label119: + bne x2, x3, label120 + addi x1, x1, 1 +label120: + bne x2, x3, label121 + addi x1, x1, 1 +label121: + bne x2, x3, label122 + addi x1, x1, 1 +label122: + bne x2, x3, label123 + addi x1, x1, 1 +label123: + bne x2, x3, label124 + addi x1, x1, 1 +label124: + bne x2, x3, label125 + addi x1, x1, 1 +label125: + bne x2, x3, label126 + addi x1, x1, 1 +label126: + bne x2, x3, label127 + addi x1, x1, 1 +label127: + bne x2, x3, label128 + addi x1, x1, 1 +label128: + bne x2, x3, label129 + addi x1, x1, 1 +label129: + bne x2, x3, label130 + addi x1, x1, 1 +label130: + bne x2, x3, label131 + addi x1, x1, 1 +label131: + bne x2, x3, label132 + addi x1, x1, 1 +label132: + bne x2, x3, label133 + addi x1, x1, 1 +label133: + bne x2, x3, label134 + addi x1, x1, 1 +label134: + bne x2, x3, label135 + addi x1, x1, 1 +label135: + bne x2, x3, label136 + addi x1, x1, 1 +label136: + bne x2, x3, label137 + addi x1, x1, 1 +label137: + bne x2, x3, label138 + addi x1, x1, 1 +label138: + bne x2, x3, label139 + addi x1, x1, 1 +label139: + bne x2, x3, label140 + addi x1, x1, 1 +label140: + bne x2, x3, label141 + addi x1, x1, 1 +label141: + bne x2, x3, label142 + addi x1, x1, 1 +label142: + bne x2, x3, label143 + addi x1, x1, 1 +label143: + bne x2, x3, label144 + addi x1, x1, 1 +label144: + bne x2, x3, label145 + addi x1, x1, 1 +label145: + bne x2, x3, label146 + addi x1, x1, 1 +label146: + bne x2, x3, label147 + addi x1, x1, 1 +label147: + bne x2, x3, label148 + addi x1, x1, 1 +label148: + bne x2, x3, label149 + addi x1, x1, 1 +label149: + bne x2, x3, label150 + addi x1, x1, 1 +label150: + bne x2, x3, label151 + addi x1, x1, 1 +label151: + bne x2, x3, label152 + addi x1, x1, 1 +label152: + bne x2, x3, label153 + addi x1, x1, 1 +label153: + bne x2, x3, label154 + addi x1, x1, 1 +label154: + bne x2, x3, label155 + addi x1, x1, 1 +label155: + bne x2, x3, label156 + addi x1, x1, 1 +label156: + bne x2, x3, label157 + addi x1, x1, 1 +label157: + bne x2, x3, label158 + addi x1, x1, 1 +label158: + bne x2, x3, label159 + addi x1, x1, 1 +label159: + bne x2, x3, label160 + addi x1, x1, 1 +label160: + bne x2, x3, label161 + addi x1, x1, 1 +label161: + bne x2, x3, label162 + addi x1, x1, 1 +label162: + bne x2, x3, label163 + addi x1, x1, 1 +label163: + bne x2, x3, label164 + addi x1, x1, 1 +label164: + bne x2, x3, label165 + addi x1, x1, 1 +label165: + bne x2, x3, label166 + addi x1, x1, 1 +label166: + bne x2, x3, label167 + addi x1, x1, 1 +label167: + bne x2, x3, label168 + addi x1, x1, 1 +label168: + bne x2, x3, label169 + addi x1, x1, 1 +label169: + bne x2, x3, label170 + addi x1, x1, 1 +label170: + bne x2, x3, label171 + addi x1, x1, 1 +label171: + bne x2, x3, label172 + addi x1, x1, 1 +label172: + bne x2, x3, label173 + addi x1, x1, 1 +label173: + bne x2, x3, label174 + addi x1, x1, 1 +label174: + bne x2, x3, label175 + addi x1, x1, 1 +label175: + bne x2, x3, label176 + addi x1, x1, 1 +label176: + bne x2, x3, label177 + addi x1, x1, 1 +label177: + bne x2, x3, label178 + addi x1, x1, 1 +label178: + bne x2, x3, label179 + addi x1, x1, 1 +label179: + bne x2, x3, label180 + addi x1, x1, 1 +label180: + bne x2, x3, label181 + addi x1, x1, 1 +label181: + bne x2, x3, label182 + addi x1, x1, 1 +label182: + bne x2, x3, label183 + addi x1, x1, 1 +label183: + bne x2, x3, label184 + addi x1, x1, 1 +label184: + bne x2, x3, label185 + addi x1, x1, 1 +label185: + bne x2, x3, label186 + addi x1, x1, 1 +label186: + bne x2, x3, label187 + addi x1, x1, 1 +label187: + bne x2, x3, label188 + addi x1, x1, 1 +label188: + bne x2, x3, label189 + addi x1, x1, 1 +label189: + bne x2, x3, label190 + addi x1, x1, 1 +label190: + bne x2, x3, label191 + addi x1, x1, 1 +label191: + bne x2, x3, label192 + addi x1, x1, 1 +label192: + bne x2, x3, label193 + addi x1, x1, 1 +label193: + bne x2, x3, label194 + addi x1, x1, 1 +label194: + bne x2, x3, label195 + addi x1, x1, 1 +label195: + bne x2, x3, label196 + addi x1, x1, 1 +label196: + bne x2, x3, label197 + addi x1, x1, 1 +label197: + bne x2, x3, label198 + addi x1, x1, 1 +label198: + bne x2, x3, label199 + addi x1, x1, 1 +label199: + bne x2, x3, label200 + addi x1, x1, 1 +label200: + bne x2, x3, label201 + addi x1, x1, 1 +label201: + bne x2, x3, label202 + addi x1, x1, 1 +label202: + bne x2, x3, label203 + addi x1, x1, 1 +label203: + bne x2, x3, label204 + addi x1, x1, 1 +label204: + bne x2, x3, label205 + addi x1, x1, 1 +label205: + bne x2, x3, label206 + addi x1, x1, 1 +label206: + bne x2, x3, label207 + addi x1, x1, 1 +label207: + bne x2, x3, label208 + addi x1, x1, 1 +label208: + bne x2, x3, label209 + addi x1, x1, 1 +label209: + bne x2, x3, label210 + addi x1, x1, 1 +label210: + bne x2, x3, label211 + addi x1, x1, 1 +label211: + bne x2, x3, label212 + addi x1, x1, 1 +label212: + bne x2, x3, label213 + addi x1, x1, 1 +label213: + bne x2, x3, label214 + addi x1, x1, 1 +label214: + bne x2, x3, label215 + addi x1, x1, 1 +label215: + bne x2, x3, label216 + addi x1, x1, 1 +label216: + bne x2, x3, label217 + addi x1, x1, 1 +label217: + bne x2, x3, label218 + addi x1, x1, 1 +label218: + bne x2, x3, label219 + addi x1, x1, 1 +label219: + bne x2, x3, label220 + addi x1, x1, 1 +label220: + bne x2, x3, label221 + addi x1, x1, 1 +label221: + bne x2, x3, label222 + addi x1, x1, 1 +label222: + bne x2, x3, label223 + addi x1, x1, 1 +label223: + bne x2, x3, label224 + addi x1, x1, 1 +label224: + bne x2, x3, label225 + addi x1, x1, 1 +label225: + bne x2, x3, label226 + addi x1, x1, 1 +label226: + bne x2, x3, label227 + addi x1, x1, 1 +label227: + bne x2, x3, label228 + addi x1, x1, 1 +label228: + bne x2, x3, label229 + addi x1, x1, 1 +label229: + bne x2, x3, label230 + addi x1, x1, 1 +label230: + bne x2, x3, label231 + addi x1, x1, 1 +label231: + bne x2, x3, label232 + addi x1, x1, 1 +label232: + bne x2, x3, label233 + addi x1, x1, 1 +label233: + bne x2, x3, label234 + addi x1, x1, 1 +label234: + bne x2, x3, label235 + addi x1, x1, 1 +label235: + bne x2, x3, label236 + addi x1, x1, 1 +label236: + bne x2, x3, label237 + addi x1, x1, 1 +label237: + bne x2, x3, label238 + addi x1, x1, 1 +label238: + bne x2, x3, label239 + addi x1, x1, 1 +label239: + bne x2, x3, label240 + addi x1, x1, 1 +label240: + bne x2, x3, label241 + addi x1, x1, 1 +label241: + bne x2, x3, label242 + addi x1, x1, 1 +label242: + bne x2, x3, label243 + addi x1, x1, 1 +label243: + bne x2, x3, label244 + addi x1, x1, 1 +label244: + bne x2, x3, label245 + addi x1, x1, 1 +label245: + bne x2, x3, label246 + addi x1, x1, 1 +label246: + bne x2, x3, label247 + addi x1, x1, 1 +label247: + bne x2, x3, label248 + addi x1, x1, 1 +label248: + bne x2, x3, label249 + addi x1, x1, 1 +label249: + bne x2, x3, label250 + addi x1, x1, 1 +label250: + bne x2, x3, label251 + addi x1, x1, 1 +label251: + bne x2, x3, label252 + addi x1, x1, 1 +label252: + bne x2, x3, label253 + addi x1, x1, 1 +label253: + bne x2, x3, label254 + addi x1, x1, 1 +label254: + bne x2, x3, label255 + addi x1, x1, 1 +label255: + bne x2, x3, label256 + addi x1, x1, 1 +label256: + bne x2, x3, label257 + addi x1, x1, 1 +label257: + bne x2, x3, label258 + addi x1, x1, 1 +label258: + bne x2, x3, label259 + addi x1, x1, 1 +label259: + bne x2, x3, label260 + addi x1, x1, 1 +label260: + bne x2, x3, label261 + addi x1, x1, 1 +label261: + bne x2, x3, label262 + addi x1, x1, 1 +label262: + bne x2, x3, label263 + addi x1, x1, 1 +label263: + bne x2, x3, label264 + addi x1, x1, 1 +label264: + bne x2, x3, label265 + addi x1, x1, 1 +label265: + bne x2, x3, label266 + addi x1, x1, 1 +label266: + bne x2, x3, label267 + addi x1, x1, 1 +label267: + bne x2, x3, label268 + addi x1, x1, 1 +label268: + bne x2, x3, label269 + addi x1, x1, 1 +label269: + bne x2, x3, label270 + addi x1, x1, 1 +label270: + bne x2, x3, label271 + addi x1, x1, 1 +label271: + bne x2, x3, label272 + addi x1, x1, 1 +label272: + bne x2, x3, label273 + addi x1, x1, 1 +label273: + bne x2, x3, label274 + addi x1, x1, 1 +label274: + bne x2, x3, label275 + addi x1, x1, 1 +label275: + bne x2, x3, label276 + addi x1, x1, 1 +label276: + bne x2, x3, label277 + addi x1, x1, 1 +label277: + bne x2, x3, label278 + addi x1, x1, 1 +label278: + bne x2, x3, label279 + addi x1, x1, 1 +label279: + bne x2, x3, label280 + addi x1, x1, 1 +label280: + bne x2, x3, label281 + addi x1, x1, 1 +label281: + bne x2, x3, label282 + addi x1, x1, 1 +label282: + bne x2, x3, label283 + addi x1, x1, 1 +label283: + bne x2, x3, label284 + addi x1, x1, 1 +label284: + bne x2, x3, label285 + addi x1, x1, 1 +label285: + bne x2, x3, label286 + addi x1, x1, 1 +label286: + bne x2, x3, label287 + addi x1, x1, 1 +label287: + bne x2, x3, label288 + addi x1, x1, 1 +label288: + bne x2, x3, label289 + addi x1, x1, 1 +label289: + bne x2, x3, label290 + addi x1, x1, 1 +label290: + bne x2, x3, label291 + addi x1, x1, 1 +label291: + bne x2, x3, label292 + addi x1, x1, 1 +label292: + bne x2, x3, label293 + addi x1, x1, 1 +label293: + bne x2, x3, label294 + addi x1, x1, 1 +label294: + bne x2, x3, label295 + addi x1, x1, 1 +label295: + bne x2, x3, label296 + addi x1, x1, 1 +label296: + bne x2, x3, label297 + addi x1, x1, 1 +label297: + bne x2, x3, label298 + addi x1, x1, 1 +label298: + bne x2, x3, label299 + addi x1, x1, 1 +label299: + bne x2, x3, label300 + addi x1, x1, 1 +label300: + bne x2, x3, label301 + addi x1, x1, 1 +label301: + bne x2, x3, label302 + addi x1, x1, 1 +label302: + bne x2, x3, label303 + addi x1, x1, 1 +label303: + bne x2, x3, label304 + addi x1, x1, 1 +label304: + bne x2, x3, label305 + addi x1, x1, 1 +label305: + bne x2, x3, label306 + addi x1, x1, 1 +label306: + bne x2, x3, label307 + addi x1, x1, 1 +label307: + bne x2, x3, label308 + addi x1, x1, 1 +label308: + bne x2, x3, label309 + addi x1, x1, 1 +label309: + bne x2, x3, label310 + addi x1, x1, 1 +label310: + bne x2, x3, label311 + addi x1, x1, 1 +label311: + bne x2, x3, label312 + addi x1, x1, 1 +label312: + bne x2, x3, label313 + addi x1, x1, 1 +label313: + bne x2, x3, label314 + addi x1, x1, 1 +label314: + bne x2, x3, label315 + addi x1, x1, 1 +label315: + bne x2, x3, label316 + addi x1, x1, 1 +label316: + bne x2, x3, label317 + addi x1, x1, 1 +label317: + bne x2, x3, label318 + addi x1, x1, 1 +label318: + bne x2, x3, label319 + addi x1, x1, 1 +label319: + bne x2, x3, label320 + addi x1, x1, 1 +label320: + bne x2, x3, label321 + addi x1, x1, 1 +label321: + bne x2, x3, label322 + addi x1, x1, 1 +label322: + bne x2, x3, label323 + addi x1, x1, 1 +label323: + bne x2, x3, label324 + addi x1, x1, 1 +label324: + bne x2, x3, label325 + addi x1, x1, 1 +label325: + bne x2, x3, label326 + addi x1, x1, 1 +label326: + bne x2, x3, label327 + addi x1, x1, 1 +label327: + bne x2, x3, label328 + addi x1, x1, 1 +label328: + bne x2, x3, label329 + addi x1, x1, 1 +label329: + bne x2, x3, label330 + addi x1, x1, 1 +label330: + bne x2, x3, label331 + addi x1, x1, 1 +label331: + bne x2, x3, label332 + addi x1, x1, 1 +label332: + bne x2, x3, label333 + addi x1, x1, 1 +label333: + bne x2, x3, label334 + addi x1, x1, 1 +label334: + bne x2, x3, label335 + addi x1, x1, 1 +label335: + bne x2, x3, label336 + addi x1, x1, 1 +label336: + bne x2, x3, label337 + addi x1, x1, 1 +label337: + bne x2, x3, label338 + addi x1, x1, 1 +label338: + bne x2, x3, label339 + addi x1, x1, 1 +label339: + bne x2, x3, label340 + addi x1, x1, 1 +label340: + bne x2, x3, label341 + addi x1, x1, 1 +label341: + bne x2, x3, label342 + addi x1, x1, 1 +label342: + bne x2, x3, label343 + addi x1, x1, 1 +label343: + bne x2, x3, label344 + addi x1, x1, 1 +label344: + bne x2, x3, label345 + addi x1, x1, 1 +label345: + bne x2, x3, label346 + addi x1, x1, 1 +label346: + bne x2, x3, label347 + addi x1, x1, 1 +label347: + bne x2, x3, label348 + addi x1, x1, 1 +label348: + bne x2, x3, label349 + addi x1, x1, 1 +label349: + bne x2, x3, label350 + addi x1, x1, 1 +label350: + bne x2, x3, label351 + addi x1, x1, 1 +label351: + bne x2, x3, label352 + addi x1, x1, 1 +label352: + bne x2, x3, label353 + addi x1, x1, 1 +label353: + bne x2, x3, label354 + addi x1, x1, 1 +label354: + bne x2, x3, label355 + addi x1, x1, 1 +label355: + bne x2, x3, label356 + addi x1, x1, 1 +label356: + bne x2, x3, label357 + addi x1, x1, 1 +label357: + bne x2, x3, label358 + addi x1, x1, 1 +label358: + bne x2, x3, label359 + addi x1, x1, 1 +label359: + bne x2, x3, label360 + addi x1, x1, 1 +label360: + bne x2, x3, label361 + addi x1, x1, 1 +label361: + bne x2, x3, label362 + addi x1, x1, 1 +label362: + bne x2, x3, label363 + addi x1, x1, 1 +label363: + bne x2, x3, label364 + addi x1, x1, 1 +label364: + bne x2, x3, label365 + addi x1, x1, 1 +label365: + bne x2, x3, label366 + addi x1, x1, 1 +label366: + bne x2, x3, label367 + addi x1, x1, 1 +label367: + bne x2, x3, label368 + addi x1, x1, 1 +label368: + bne x2, x3, label369 + addi x1, x1, 1 +label369: + bne x2, x3, label370 + addi x1, x1, 1 +label370: + bne x2, x3, label371 + addi x1, x1, 1 +label371: + bne x2, x3, label372 + addi x1, x1, 1 +label372: + bne x2, x3, label373 + addi x1, x1, 1 +label373: + bne x2, x3, label374 + addi x1, x1, 1 +label374: + bne x2, x3, label375 + addi x1, x1, 1 +label375: + bne x2, x3, label376 + addi x1, x1, 1 +label376: + bne x2, x3, label377 + addi x1, x1, 1 +label377: + bne x2, x3, label378 + addi x1, x1, 1 +label378: + bne x2, x3, label379 + addi x1, x1, 1 +label379: + bne x2, x3, label380 + addi x1, x1, 1 +label380: + bne x2, x3, label381 + addi x1, x1, 1 +label381: + bne x2, x3, label382 + addi x1, x1, 1 +label382: + bne x2, x3, label383 + addi x1, x1, 1 +label383: + bne x2, x3, label384 + addi x1, x1, 1 +label384: + bne x2, x3, label385 + addi x1, x1, 1 +label385: + bne x2, x3, label386 + addi x1, x1, 1 +label386: + bne x2, x3, label387 + addi x1, x1, 1 +label387: + bne x2, x3, label388 + addi x1, x1, 1 +label388: + bne x2, x3, label389 + addi x1, x1, 1 +label389: + bne x2, x3, label390 + addi x1, x1, 1 +label390: + bne x2, x3, label391 + addi x1, x1, 1 +label391: + bne x2, x3, label392 + addi x1, x1, 1 +label392: + bne x2, x3, label393 + addi x1, x1, 1 +label393: + bne x2, x3, label394 + addi x1, x1, 1 +label394: + bne x2, x3, label395 + addi x1, x1, 1 +label395: + bne x2, x3, label396 + addi x1, x1, 1 +label396: + bne x2, x3, label397 + addi x1, x1, 1 +label397: + bne x2, x3, label398 + addi x1, x1, 1 +label398: + bne x2, x3, label399 + addi x1, x1, 1 +label399: + bne x2, x3, label400 + addi x1, x1, 1 +label400: + bne x2, x3, label401 + addi x1, x1, 1 +label401: + bne x2, x3, label402 + addi x1, x1, 1 +label402: + bne x2, x3, label403 + addi x1, x1, 1 +label403: + bne x2, x3, label404 + addi x1, x1, 1 +label404: + bne x2, x3, label405 + addi x1, x1, 1 +label405: + bne x2, x3, label406 + addi x1, x1, 1 +label406: + bne x2, x3, label407 + addi x1, x1, 1 +label407: + bne x2, x3, label408 + addi x1, x1, 1 +label408: + bne x2, x3, label409 + addi x1, x1, 1 +label409: + bne x2, x3, label410 + addi x1, x1, 1 +label410: + bne x2, x3, label411 + addi x1, x1, 1 +label411: + bne x2, x3, label412 + addi x1, x1, 1 +label412: + bne x2, x3, label413 + addi x1, x1, 1 +label413: + bne x2, x3, label414 + addi x1, x1, 1 +label414: + bne x2, x3, label415 + addi x1, x1, 1 +label415: + bne x2, x3, label416 + addi x1, x1, 1 +label416: + bne x2, x3, label417 + addi x1, x1, 1 +label417: + bne x2, x3, label418 + addi x1, x1, 1 +label418: + bne x2, x3, label419 + addi x1, x1, 1 +label419: + bne x2, x3, label420 + addi x1, x1, 1 +label420: + bne x2, x3, label421 + addi x1, x1, 1 +label421: + bne x2, x3, label422 + addi x1, x1, 1 +label422: + bne x2, x3, label423 + addi x1, x1, 1 +label423: + bne x2, x3, label424 + addi x1, x1, 1 +label424: + bne x2, x3, label425 + addi x1, x1, 1 +label425: + bne x2, x3, label426 + addi x1, x1, 1 +label426: + bne x2, x3, label427 + addi x1, x1, 1 +label427: + bne x2, x3, label428 + addi x1, x1, 1 +label428: + bne x2, x3, label429 + addi x1, x1, 1 +label429: + bne x2, x3, label430 + addi x1, x1, 1 +label430: + bne x2, x3, label431 + addi x1, x1, 1 +label431: + bne x2, x3, label432 + addi x1, x1, 1 +label432: + bne x2, x3, label433 + addi x1, x1, 1 +label433: + bne x2, x3, label434 + addi x1, x1, 1 +label434: + bne x2, x3, label435 + addi x1, x1, 1 +label435: + bne x2, x3, label436 + addi x1, x1, 1 +label436: + bne x2, x3, label437 + addi x1, x1, 1 +label437: + bne x2, x3, label438 + addi x1, x1, 1 +label438: + bne x2, x3, label439 + addi x1, x1, 1 +label439: + bne x2, x3, label440 + addi x1, x1, 1 +label440: + bne x2, x3, label441 + addi x1, x1, 1 +label441: + bne x2, x3, label442 + addi x1, x1, 1 +label442: + bne x2, x3, label443 + addi x1, x1, 1 +label443: + bne x2, x3, label444 + addi x1, x1, 1 +label444: + bne x2, x3, label445 + addi x1, x1, 1 +label445: + bne x2, x3, label446 + addi x1, x1, 1 +label446: + bne x2, x3, label447 + addi x1, x1, 1 +label447: + bne x2, x3, label448 + addi x1, x1, 1 +label448: + bne x2, x3, label449 + addi x1, x1, 1 +label449: + bne x2, x3, label450 + addi x1, x1, 1 +label450: + bne x2, x3, label451 + addi x1, x1, 1 +label451: + bne x2, x3, label452 + addi x1, x1, 1 +label452: + bne x2, x3, label453 + addi x1, x1, 1 +label453: + bne x2, x3, label454 + addi x1, x1, 1 +label454: + bne x2, x3, label455 + addi x1, x1, 1 +label455: + bne x2, x3, label456 + addi x1, x1, 1 +label456: + bne x2, x3, label457 + addi x1, x1, 1 +label457: + bne x2, x3, label458 + addi x1, x1, 1 +label458: + bne x2, x3, label459 + addi x1, x1, 1 +label459: + bne x2, x3, label460 + addi x1, x1, 1 +label460: + bne x2, x3, label461 + addi x1, x1, 1 +label461: + bne x2, x3, label462 + addi x1, x1, 1 +label462: + bne x2, x3, label463 + addi x1, x1, 1 +label463: + bne x2, x3, label464 + addi x1, x1, 1 +label464: + bne x2, x3, label465 + addi x1, x1, 1 +label465: + bne x2, x3, label466 + addi x1, x1, 1 +label466: + bne x2, x3, label467 + addi x1, x1, 1 +label467: + bne x2, x3, label468 + addi x1, x1, 1 +label468: + bne x2, x3, label469 + addi x1, x1, 1 +label469: + bne x2, x3, label470 + addi x1, x1, 1 +label470: + bne x2, x3, label471 + addi x1, x1, 1 +label471: + bne x2, x3, label472 + addi x1, x1, 1 +label472: + bne x2, x3, label473 + addi x1, x1, 1 +label473: + bne x2, x3, label474 + addi x1, x1, 1 +label474: + bne x2, x3, label475 + addi x1, x1, 1 +label475: + bne x2, x3, label476 + addi x1, x1, 1 +label476: + bne x2, x3, label477 + addi x1, x1, 1 +label477: + bne x2, x3, label478 + addi x1, x1, 1 +label478: + bne x2, x3, label479 + addi x1, x1, 1 +label479: + bne x2, x3, label480 + addi x1, x1, 1 +label480: + bne x2, x3, label481 + addi x1, x1, 1 +label481: + bne x2, x3, label482 + addi x1, x1, 1 +label482: + bne x2, x3, label483 + addi x1, x1, 1 +label483: + bne x2, x3, label484 + addi x1, x1, 1 +label484: + bne x2, x3, label485 + addi x1, x1, 1 +label485: + bne x2, x3, label486 + addi x1, x1, 1 +label486: + bne x2, x3, label487 + addi x1, x1, 1 +label487: + bne x2, x3, label488 + addi x1, x1, 1 +label488: + bne x2, x3, label489 + addi x1, x1, 1 +label489: + bne x2, x3, label490 + addi x1, x1, 1 +label490: + bne x2, x3, label491 + addi x1, x1, 1 +label491: + bne x2, x3, label492 + addi x1, x1, 1 +label492: + bne x2, x3, label493 + addi x1, x1, 1 +label493: + bne x2, x3, label494 + addi x1, x1, 1 +label494: + bne x2, x3, label495 + addi x1, x1, 1 +label495: + bne x2, x3, label496 + addi x1, x1, 1 +label496: + bne x2, x3, label497 + addi x1, x1, 1 +label497: + bne x2, x3, label498 + addi x1, x1, 1 +label498: + bne x2, x3, label499 + addi x1, x1, 1 +label499: + + + /* Write counter into DEM. */ + la x5, res + sw x1, 0(x5) + + ecall + +.data + .balign 32 + .globl res + res: + .zero 4 diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c index 08bb9e4e68efc..900a11baeba28 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.c @@ -368,6 +368,52 @@ status_t handle_otbn_fi_char_bn_wsrr(ujson_t *uj) { return OK_STATUS(); } +status_t handle_otbn_fi_char_bne(ujson_t *uj) { + // Clear registered alerts in alert handler. + pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); + + // Initialize OTBN app, load it, and get interface to OTBN data memory. + OTBN_DECLARE_APP_SYMBOLS(otbn_char_bne); + OTBN_DECLARE_SYMBOL_ADDR(otbn_char_bne, res); + const otbn_app_t kOtbnAppCharBne = OTBN_APP_T_INIT(otbn_char_bne); + static const otbn_addr_t kOtbnAppCharBneRes = + OTBN_ADDR_T_INIT(otbn_char_bne, res); + otbn_load_app(kOtbnAppCharBne); + + // FI code target. + pentest_set_trigger_high(); + otbn_execute(); + otbn_busy_wait_for_done(); + pentest_set_trigger_low(); + + // Get registered alerts from alert handler. + reg_alerts = pentest_get_triggered_alerts(); + // Read counter (x1) from OTBN data memory. + otbn_fi_result_cnt_t uj_output; + uj_output.result = 0; + otbn_dmem_read(1, kOtbnAppCharBneRes, &uj_output.result); + + // Read OTBN instruction counter. + TRY(dif_otbn_get_insn_cnt(&otbn, &uj_output.insn_cnt)); + + // Read ERR_STATUS register from OTBN. + dif_otbn_err_bits_t err_otbn; + read_otbn_err_bits(&err_otbn); + + // Read ERR_STATUS register from Ibex. + dif_rv_core_ibex_error_status_t err_ibx; + TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx)); + // Clear OTBN memory. + TRY(clear_otbn()); + + // Send back to host. + uj_output.err_otbn = err_otbn; + uj_output.err_ibx = err_ibx; + memcpy(uj_output.alerts, reg_alerts.alerts, sizeof(reg_alerts.alerts)); + RESP_OK(ujson_serialize_otbn_fi_result_cnt_t, uj, &uj_output); + return OK_STATUS(); +} + status_t handle_otbn_fi_char_dmem_access(ujson_t *uj) { // Clear registered alerts in alert handler. pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); @@ -1288,7 +1334,7 @@ status_t handle_otbn_fi_pc(ujson_t *uj) { // Get OTBN program counter from host. otbn_fi_pc_t uj_data; TRY(ujson_deserialize_otbn_fi_pc_t(uj, &uj_data)); - + // Clear registered alerts in alert handler. pentest_registered_alerts_t reg_alerts = pentest_get_triggered_alerts(); @@ -1310,7 +1356,7 @@ status_t handle_otbn_fi_pc(ujson_t *uj) { otbn_execute(); // Wait until is started before deasserting the trigger. bool is_running = false; - while(!is_running) { + while (!is_running) { TRY(dif_otbn_get_status(&otbn, &otbn_status)); if (otbn_status != kDifOtbnStatusIdle) { is_running = true; @@ -1323,8 +1369,10 @@ status_t handle_otbn_fi_pc(ujson_t *uj) { // Read pc_out from OTBN data memory. otbn_fi_pc_out_t uj_output; - TRY(dif_otbn_dmem_read(&otbn, kOtbnPcOut, &uj_output.pc_otbn, sizeof(uj_output.pc_otbn))); - TRY(dif_otbn_dmem_read(&otbn, kOtbnPc, &uj_output.pc_dmem, sizeof(uj_output.pc_dmem))); + TRY(dif_otbn_dmem_read(&otbn, kOtbnPcOut, &uj_output.pc_otbn, + sizeof(uj_output.pc_otbn))); + TRY(dif_otbn_dmem_read(&otbn, kOtbnPc, &uj_output.pc_dmem, + sizeof(uj_output.pc_dmem))); // Read OTBN instruction counter. TRY(dif_otbn_get_insn_cnt(&otbn, &uj_output.insn_cnt)); @@ -1360,6 +1408,8 @@ status_t handle_otbn_fi(ujson_t *uj) { return handle_otbn_fi_char_bn_sel(uj); case kOtbnFiSubcommandCharBnWsrr: return handle_otbn_fi_char_bn_wsrr(uj); + case kOtbnFiSubcommandCharBne: + return handle_otbn_fi_char_bne(uj); case kOtbnFiSubcommandCharDmemAccess: return handle_otbn_fi_char_dmem_access(uj); case kOtbnFiSubcommandCharDmemWrite: diff --git a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h index 860d98525b418..3c013a70c5697 100644 --- a/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h +++ b/sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h @@ -60,6 +60,20 @@ status_t handle_otbn_fi_char_bn_sel(ujson_t *uj); */ status_t handle_otbn_fi_char_bn_wsrr(ujson_t *uj); +/** + * otbn.fi.char.bne command handler. + * + * The goal of this test is to fault to BNE instruction such that the jump is + * not performed. Then, a counter gets incremented. When no effective fault + * occurs, the counter is 0. + * + * Faults are injected during the trigger_high & trigger_low. + * It needs to be ensured that the compiler does not optimize this code. + * + * @param uj The received uJSON data. + */ +status_t handle_otbn_fi_char_bne(ujson_t *uj); + /** * otbn.fi.char_dmem_access command handler. * @@ -252,9 +266,9 @@ status_t handle_otbn_fi_load_integrity(ujson_t *uj); /** * otbn.fi.pc command handler. * - * The goal of this test is to fault the OTBN program counter that is passed from - * Ibex into OTBN. OTBN jumps to this PC. Manipulation can be detected by reading - * the instruction counter. + * The goal of this test is to fault the OTBN program counter that is passed + * from Ibex into OTBN. OTBN jumps to this PC. Manipulation can be detected by + * reading the instruction counter. * * @param uj The received uJSON data. */ diff --git a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h index 7b575d292573d..590bd1d568f4b 100644 --- a/sw/device/tests/penetrationtests/json/otbn_fi_commands.h +++ b/sw/device/tests/penetrationtests/json/otbn_fi_commands.h @@ -16,6 +16,7 @@ extern "C" { value(_, CharBnRshi) \ value(_, CharBnSel) \ value(_, CharBnWsrr) \ + value(_, CharBne) \ value(_, CharDmemAccess) \ value(_, CharDmemWrite) \ value(_, CharHardwareDmemOpLoop) \ From b0d24d1f559c2ec5b2ec65730a12c0402d256ef9 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Wed, 11 Dec 2024 07:56:08 +0100 Subject: [PATCH 9/9] [pentest] Add otbn_busy_wait For english breakfast targets, we are not waiting for the otbn to be finished. However, for the other targets, we should do this. Signed-off-by: Pascal Nasahl (cherry picked from commit 0b13417925764d662582c4cfd00366221c9d1437) --- .../tests/penetrationtests/firmware/lib/pentest_lib.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.c b/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.c index bbed0866ebe29..ea46d1d0f2ae6 100644 --- a/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.c +++ b/sw/device/tests/penetrationtests/firmware/lib/pentest_lib.c @@ -576,11 +576,11 @@ void pentest_call_and_sleep(sca_callee callee, uint32_t sleep_cycles, wait_for_interrupt(); - // #if !OT_IS_ENGLISH_BREAKFAST - // if (otbn) { - // otbn_busy_wait_for_done(); - // } - // #endif +#if !OT_IS_ENGLISH_BREAKFAST + if (otbn) { + otbn_busy_wait_for_done(); + } +#endif if (sw_trigger) { pentest_set_trigger_low();