5 #include "sw/device/tests/penetrationtests/firmware/fi/otbn_fi.h"
8 #include "sw/device/lib/base/status.h"
9 #include "sw/device/lib/crypto/drivers/keymgr.h"
10 #include "sw/device/lib/crypto/drivers/otbn.h"
12 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
14 #include "sw/device/lib/testing/entropy_testutils.h"
15 #include "sw/device/lib/testing/keymgr_testutils.h"
16 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
17 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
18 #include "sw/device/lib/ujson/ujson.h"
19 #include "sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h"
20 #include "sw/device/tests/penetrationtests/json/otbn_fi_commands.h"
23 #include "otbn_regs.h"
26 static dif_rv_core_ibex_t rv_core_ibex;
28 static dif_otbn_t otbn;
29 static dif_keymgr_t keymgr;
32 static bool load_integrity_init;
34 static bool char_mem_init;
36 static bool char_mem_test_cfg_valid;
38 static uint32_t load_checksum_ref;
45 static const otbn_app_t kOtbnAppLoadIntegrity =
47 static const otbn_addr_t kOtbnAppLoadIntegrityRefVal1 =
49 static const otbn_addr_t kOtbnAppLoadIntegrityRefVal2 =
51 static const otbn_addr_t kOtbnAppLoadIntegrityRefVal3 =
55 static bool key_sideloading_init;
64 static const otbn_addr_t kOtbnAppKeySideloadks0l =
66 static const otbn_addr_t kOtbnAppKeySideloadks0h =
68 static const otbn_addr_t kOtbnAppKeySideloadks1l =
70 static const otbn_addr_t kOtbnAppKeySideloadks1h =
74 static bool char_mem_imem;
75 static bool char_mem_dmem;
76 static uint32_t char_mem_byte_offset;
77 static uint32_t char_mem_num_words;
79 uint32_t key_share_0_l_ref, key_share_0_h_ref;
80 uint32_t key_share_1_l_ref, key_share_1_h_ref;
83 #define NOP1 "addi x0, x0, 0\n"
84 #define NOP10 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1
85 #define NOP30 NOP10 NOP10 NOP10
86 #define NOP100 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10
89 static const uint32_t ref_values[32] = {
90 0x1BADB002, 0x8BADF00D, 0xA5A5A5A5, 0xABABABAB, 0xABBABABE, 0xABADCAFE,
91 0xBAAAAAAD, 0xBAD22222, 0xBBADBEEF, 0xBEBEBEBE, 0xBEEFCACE, 0xC00010FF,
92 0xCAFED00D, 0xCAFEFEED, 0xCCCCCCCC, 0xCDCDCDCD, 0x0D15EA5E, 0xDEAD10CC,
93 0xDEADBEEF, 0xDEADCAFE, 0xDEADC0DE, 0xDEADFA11, 0xDEADF00D, 0xDEFEC8ED,
94 0xDEADDEAD, 0xD00D2BAD, 0xEBEBEBEB, 0xFADEDEAD, 0xFDFDFDFD, 0xFEE1DEAD,
95 0xFEEDFACE, 0xFEEEFEEE};
120 TRY(otbn_dmem_sec_wipe());
121 TRY(otbn_imem_sec_wipe());
141 status_t read_otbn_load_checksum(uint32_t *checksum) {
149 status_t clear_otbn_load_checksum(
void) {
158 pentest_clear_sensor_recov_alerts();
164 static const otbn_addr_t kOtbnAppCharBeqRes =
166 otbn_load_app(kOtbnAppCharBeq);
169 pentest_set_trigger_high();
171 otbn_busy_wait_for_done();
172 pentest_set_trigger_low();
174 reg_alerts = pentest_get_triggered_alerts();
179 otbn_fi_result_cnt_t uj_output;
180 uj_output.result = 0;
181 otbn_dmem_read(1, kOtbnAppCharBeqRes, &uj_output.result);
188 read_otbn_err_bits(&err_otbn);
191 dif_rv_core_ibex_error_status_t err_ibx;
192 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
198 uj_output.err_otbn = err_otbn;
199 uj_output.err_ibx = err_ibx;
200 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
201 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
202 sizeof(sensor_alerts.alerts));
203 RESP_OK(ujson_serialize_otbn_fi_result_cnt_t, uj, &uj_output);
209 otbn_fi_big_num_t uj_data;
210 TRY(ujson_deserialize_otbn_fi_big_num_t(uj, &uj_data));
215 pentest_clear_sensor_recov_alerts();
222 static const otbn_addr_t kOtbnAppCharBnRshiBigNum =
224 static const otbn_addr_t kOtbnAppCharBnRshiBigNumOut =
228 otbn_load_app(kOtbnAppCharBnRshi);
230 sizeof(uj_data.big_num)));
233 pentest_set_trigger_high();
235 otbn_busy_wait_for_done();
236 pentest_set_trigger_low();
238 reg_alerts = pentest_get_triggered_alerts();
243 otbn_fi_big_num_out_t uj_output;
244 memset(uj_output.big_num, 0,
sizeof(uj_output.big_num));
246 sizeof(uj_output.big_num)));
253 read_otbn_err_bits(&err_otbn);
256 dif_rv_core_ibex_error_status_t err_ibx;
257 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
263 uj_output.err_otbn = err_otbn;
264 uj_output.err_ibx = err_ibx;
265 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
266 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
267 sizeof(sensor_alerts.alerts));
268 RESP_OK(ujson_serialize_otbn_fi_big_num_out_t, uj, &uj_output);
274 otbn_fi_big_num_t uj_data;
275 TRY(ujson_deserialize_otbn_fi_big_num_t(uj, &uj_data));
280 pentest_clear_sensor_recov_alerts();
287 static const otbn_addr_t kOtbnAppCharBnSelBigNum =
289 static const otbn_addr_t kOtbnAppCharBnSelBigNumOut =
293 otbn_load_app(kOtbnAppCharBnSel);
295 sizeof(uj_data.big_num)));
298 pentest_set_trigger_high();
300 otbn_busy_wait_for_done();
301 pentest_set_trigger_low();
303 reg_alerts = pentest_get_triggered_alerts();
308 otbn_fi_big_num_out_t uj_output;
309 memset(uj_output.big_num, 0,
sizeof(uj_output.big_num));
311 sizeof(uj_output.big_num)));
318 read_otbn_err_bits(&err_otbn);
321 dif_rv_core_ibex_error_status_t err_ibx;
322 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
328 uj_output.err_otbn = err_otbn;
329 uj_output.err_ibx = err_ibx;
330 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
331 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
332 sizeof(sensor_alerts.alerts));
333 RESP_OK(ujson_serialize_otbn_fi_big_num_out_t, uj, &uj_output);
341 pentest_clear_sensor_recov_alerts();
347 static const otbn_addr_t kOtbnAppCharBnWsrrResValuesWDR =
351 otbn_load_app(kOtbnAppCharBnWsrr);
354 pentest_set_trigger_high();
356 otbn_busy_wait_for_done();
357 pentest_set_trigger_low();
360 reg_alerts = pentest_get_triggered_alerts();
366 read_otbn_err_bits(&err_otbn);
369 dif_rv_core_ibex_error_status_t err_ibx;
370 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
373 otbn_fi_data_t uj_output;
375 memset(uj_output.data, 0,
sizeof(uj_output.data));
377 sizeof(uj_output.data)));
385 uj_output.err_otbn = err_otbn;
386 uj_output.err_ibx = err_ibx;
387 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
388 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
389 sizeof(sensor_alerts.alerts));
390 RESP_OK(ujson_serialize_otbn_fi_data_t, uj, &uj_output);
399 pentest_clear_sensor_recov_alerts();
405 static const otbn_addr_t kOtbnAppCharBneRes =
407 otbn_load_app(kOtbnAppCharBne);
410 pentest_set_trigger_high();
412 otbn_busy_wait_for_done();
413 pentest_set_trigger_low();
416 reg_alerts = pentest_get_triggered_alerts();
420 otbn_fi_result_cnt_t uj_output;
421 uj_output.result = 0;
422 otbn_dmem_read(1, kOtbnAppCharBneRes, &uj_output.result);
429 read_otbn_err_bits(&err_otbn);
432 dif_rv_core_ibex_error_status_t err_ibx;
433 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
438 uj_output.err_otbn = err_otbn;
439 uj_output.err_ibx = err_ibx;
440 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
441 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
442 sizeof(sensor_alerts.alerts));
443 RESP_OK(ujson_serialize_otbn_fi_result_cnt_t, uj, &uj_output);
451 pentest_clear_sensor_recov_alerts();
456 static const otbn_app_t kOtbnAppCharDmemAccess =
458 static const otbn_addr_t kOtbnVarCharDmemAccessValues =
461 otbn_load_app(kOtbnAppCharDmemAccess);
464 pentest_set_trigger_high();
466 otbn_busy_wait_for_done();
467 pentest_set_trigger_low();
470 reg_alerts = pentest_get_triggered_alerts();
476 read_otbn_err_bits(&err_otbn);
479 dif_rv_core_ibex_error_status_t err_ibx;
480 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
483 otbn_fi_data_t uj_output;
485 memset(uj_output.data, 0,
sizeof(uj_output.data));
487 sizeof(uj_output.data)));
492 uj_output.err_otbn = err_otbn;
493 uj_output.err_ibx = err_ibx;
494 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
495 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
496 sizeof(sensor_alerts.alerts));
497 RESP_OK(ujson_serialize_otbn_fi_data_t, uj, &uj_output);
506 pentest_clear_sensor_recov_alerts();
512 static const otbn_app_t kOtbnAppCharDmemWrite =
514 static const otbn_addr_t kOtbnVarCharDmemWriteMem =
518 otbn_load_app(kOtbnAppCharDmemWrite);
520 pentest_set_trigger_high();
525 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem),
529 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 4),
533 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 8),
537 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 12),
541 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 16),
545 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 20),
549 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 24),
553 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 28),
557 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 32),
561 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 36),
565 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 40),
569 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 44),
573 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 48),
577 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 52),
581 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 56),
585 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 60),
589 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 64),
593 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 68),
597 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 72),
601 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 76),
605 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 80),
609 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 84),
613 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 88),
617 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 92),
621 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 96),
625 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 100),
629 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 104),
633 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 108),
637 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 112),
641 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 116),
645 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 120),
649 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 124),
652 pentest_set_trigger_low();
656 otbn_busy_wait_for_done();
659 reg_alerts = pentest_get_triggered_alerts();
665 read_otbn_err_bits(&err_otbn);
668 dif_rv_core_ibex_error_status_t err_ibx;
669 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
672 otbn_fi_result_array_t uj_output;
673 uint32_t res_values[
ARRAYSIZE(ref_values)];
674 memset(res_values, 0,
sizeof(res_values));
676 sizeof(res_values)));
677 for (
size_t it = 0; it <
ARRAYSIZE(ref_values); it++) {
678 uj_output.result[it] = res_values[it] ^ ref_values[it];
688 uj_output.err_otbn = err_otbn;
689 uj_output.err_ibx = err_ibx;
690 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
691 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
692 sizeof(sensor_alerts.alerts));
693 RESP_OK(ujson_serialize_otbn_fi_result_array_t, uj, &uj_output);
702 pentest_clear_sensor_recov_alerts();
707 const otbn_app_t kOtbnAppCharHardwareDmemOpLoop =
709 static const otbn_addr_t kOtbnAppCharHardwareDmemOpLoopLC =
711 otbn_load_app(kOtbnAppCharHardwareDmemOpLoop);
713 uint32_t loop_counter;
716 pentest_set_trigger_high();
718 otbn_busy_wait_for_done();
719 pentest_set_trigger_low();
721 reg_alerts = pentest_get_triggered_alerts();
726 otbn_dmem_read(1, kOtbnAppCharHardwareDmemOpLoopLC, &loop_counter);
730 read_otbn_err_bits(&err_otbn);
733 dif_rv_core_ibex_error_status_t err_ibx;
734 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
740 otbn_fi_loop_counter_t uj_output;
741 uj_output.loop_counter = loop_counter;
742 uj_output.err_otbn = err_otbn;
743 uj_output.err_ibx = err_ibx;
744 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
745 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
746 sizeof(sensor_alerts.alerts));
747 RESP_OK(ujson_serialize_otbn_fi_loop_counter_t, uj, &uj_output);
755 pentest_clear_sensor_recov_alerts();
760 const otbn_app_t kOtbnAppCharHardwareRegOpLoop =
762 static const otbn_addr_t kOtbnAppCharHardwareRegOpLoopLC =
764 otbn_load_app(kOtbnAppCharHardwareRegOpLoop);
766 uint32_t loop_counter;
769 pentest_set_trigger_high();
771 otbn_busy_wait_for_done();
772 pentest_set_trigger_low();
774 reg_alerts = pentest_get_triggered_alerts();
779 otbn_dmem_read(1, kOtbnAppCharHardwareRegOpLoopLC, &loop_counter);
783 read_otbn_err_bits(&err_otbn);
786 dif_rv_core_ibex_error_status_t err_ibx;
787 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
793 otbn_fi_loop_counter_t uj_output;
794 uj_output.loop_counter = loop_counter;
795 uj_output.err_otbn = err_otbn;
796 uj_output.err_ibx = err_ibx;
797 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
798 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
799 sizeof(sensor_alerts.alerts));
800 RESP_OK(ujson_serialize_otbn_fi_loop_counter_t, uj, &uj_output);
808 pentest_clear_sensor_recov_alerts();
814 static const otbn_addr_t kOtbnAppCharJalRes =
816 otbn_load_app(kOtbnAppCharJal);
819 pentest_set_trigger_high();
821 otbn_busy_wait_for_done();
822 pentest_set_trigger_low();
824 reg_alerts = pentest_get_triggered_alerts();
829 otbn_fi_result_cnt_t uj_output;
830 uj_output.result = 0;
831 otbn_dmem_read(1, kOtbnAppCharJalRes, &uj_output.result);
838 read_otbn_err_bits(&err_otbn);
841 dif_rv_core_ibex_error_status_t err_ibx;
842 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
848 uj_output.err_otbn = err_otbn;
849 uj_output.err_ibx = err_ibx;
850 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
851 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
852 sizeof(sensor_alerts.alerts));
853 RESP_OK(ujson_serialize_otbn_fi_result_cnt_t, uj, &uj_output);
861 pentest_clear_sensor_recov_alerts();
868 static const otbn_addr_t kOtbnMemIn =
OTBN_ADDR_T_INIT(otbn_char_lw, mem_in);
869 static const otbn_addr_t kOtbnMemOut =
873 otbn_load_app(kOtbnAppCharLw);
877 pentest_set_trigger_high();
879 otbn_busy_wait_for_done();
880 pentest_set_trigger_low();
883 reg_alerts = pentest_get_triggered_alerts();
888 otbn_fi_result_array_t uj_output;
889 uint32_t res_values[29];
890 memset(res_values, 0,
sizeof(res_values));
891 memset(uj_output.result, 0,
sizeof(uj_output.result));
893 for (
size_t it = 0; it < 29; it++) {
894 uj_output.result[it] = res_values[it] ^ ref_values[it];
902 read_otbn_err_bits(&err_otbn);
905 dif_rv_core_ibex_error_status_t err_ibx;
906 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
912 uj_output.err_otbn = err_otbn;
913 uj_output.err_ibx = err_ibx;
914 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
915 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
916 sizeof(sensor_alerts.alerts));
917 RESP_OK(ujson_serialize_otbn_fi_result_array_t, uj, &uj_output);
924 if (!char_mem_test_cfg_valid) {
925 otbn_fi_mem_cfg_t uj_cfg;
926 TRY(ujson_deserialize_otbn_fi_mem_cfg_t(uj, &uj_cfg));
927 char_mem_imem = uj_cfg.imem;
928 char_mem_dmem = uj_cfg.dmem;
929 char_mem_byte_offset = uj_cfg.byte_offset;
930 char_mem_num_words = uj_cfg.num_words;
932 char_mem_test_cfg_valid =
true;
938 pentest_clear_sensor_recov_alerts();
941 uint32_t dmem_array_ref[char_mem_num_words];
942 uint32_t imem_array_ref[char_mem_num_words];
944 memset(dmem_array_ref, 0xab,
sizeof(dmem_array_ref));
947 memset(imem_array_ref, 0xdf,
sizeof(imem_array_ref));
950 if (!char_mem_init) {
953 sizeof(dmem_array_ref)));
957 sizeof(imem_array_ref)));
959 char_mem_init =
true;
963 pentest_set_trigger_high();
964 asm volatile(NOP100);
965 pentest_set_trigger_low();
968 reg_alerts = pentest_get_triggered_alerts();
974 read_otbn_err_bits(&err_otbn);
977 dif_rv_core_ibex_error_status_t err_ibx;
978 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
980 otbn_fi_mem_t uj_output;
982 memset(uj_output.dmem_data, 0,
sizeof(uj_output.dmem_data));
983 memset(uj_output.dmem_addr, 0,
sizeof(uj_output.dmem_addr));
984 memset(uj_output.imem_data, 0,
sizeof(uj_output.imem_data));
985 memset(uj_output.imem_addr, 0,
sizeof(uj_output.imem_addr));
989 size_t fault_pos = 0;
991 uint32_t dmem_array_res[char_mem_num_words];
993 sizeof(dmem_array_ref)));
994 for (
size_t it = 0; it < char_mem_num_words; it++) {
995 if (dmem_array_res[it] != dmem_array_ref[it] &&
996 fault_pos <
ARRAYSIZE(uj_output.dmem_data)) {
997 uj_output.dmem_data[fault_pos] = dmem_array_res[it];
998 uj_output.dmem_addr[fault_pos] = it;
1001 char_mem_init =
false;
1008 uint32_t imem_array_res[char_mem_num_words];
1009 if (char_mem_imem) {
1011 sizeof(imem_array_ref)));
1013 for (
size_t it = 0; it < char_mem_num_words; it++) {
1014 if (imem_array_res[it] != imem_array_ref[it] &&
1015 fault_pos <
ARRAYSIZE(uj_output.imem_data)) {
1016 uj_output.imem_data[fault_pos] = imem_array_res[it];
1017 uj_output.imem_addr[fault_pos] = it;
1020 char_mem_init =
false;
1027 uj_output.err_otbn = err_otbn;
1028 uj_output.err_ibx = err_ibx;
1029 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1030 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1031 sizeof(sensor_alerts.alerts));
1032 RESP_OK(ujson_serialize_otbn_fi_mem_t, uj, &uj_output);
1041 pentest_clear_sensor_recov_alerts();
1050 static const otbn_addr_t kOtbnVarCharRFRefValues =
1052 static const otbn_addr_t kOtbnVarCharRFResValuesGPR =
1054 static const otbn_addr_t kOtbnVarCharRFResValuesWDR =
1058 otbn_load_app(kOtbnAppCharRF);
1060 sizeof(ref_values)));
1062 pentest_set_trigger_high();
1064 otbn_busy_wait_for_done();
1065 pentest_set_trigger_low();
1068 reg_alerts = pentest_get_triggered_alerts();
1074 read_otbn_err_bits(&err_otbn);
1077 dif_rv_core_ibex_error_status_t err_ibx;
1078 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1081 uint32_t res_values_gpr[29];
1082 memset(res_values_gpr, 0,
sizeof(res_values_gpr));
1084 sizeof(res_values_gpr)));
1087 otbn_fi_rf_char_t uj_output;
1088 memset(uj_output.faulty_gpr, 0,
sizeof(uj_output.faulty_gpr));
1090 for (
size_t it = 0; it <
ARRAYSIZE(res_values_gpr); it++) {
1091 if (res_values_gpr[it] != ref_values[it]) {
1095 uj_output.faulty_gpr[it] = res_values_gpr[it] ^ ref_values[it];
1100 uint32_t res_values_wdr[256];
1101 memset(res_values_wdr, 0,
sizeof(res_values_wdr));
1103 sizeof(res_values_wdr)));
1106 memset(uj_output.faulty_wdr, 0,
sizeof(uj_output.faulty_wdr));
1107 for (
size_t it = 0; it <
ARRAYSIZE(res_values_wdr); it++) {
1108 if (res_values_wdr[it] != ref_values[it % 32]) {
1112 uj_output.faulty_wdr[it] = res_values_wdr[it] ^ ref_values[it % 32];
1117 uj_output.err_otbn = err_otbn;
1118 uj_output.err_ibx = err_ibx;
1119 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1120 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1121 sizeof(sensor_alerts.alerts));
1122 RESP_OK(ujson_serialize_otbn_fi_rf_char_t, uj, &uj_output);
1131 pentest_clear_sensor_recov_alerts();
1136 const otbn_app_t kOtbnAppCharUnrolledDmemOpLoop =
1138 static const otbn_addr_t kOtbnAppCharUnrolledDmemOpLoopLC =
1140 otbn_load_app(kOtbnAppCharUnrolledDmemOpLoop);
1142 uint32_t loop_counter;
1145 pentest_set_trigger_high();
1147 otbn_busy_wait_for_done();
1148 pentest_set_trigger_low();
1150 reg_alerts = pentest_get_triggered_alerts();
1155 otbn_dmem_read(1, kOtbnAppCharUnrolledDmemOpLoopLC, &loop_counter);
1159 read_otbn_err_bits(&err_otbn);
1162 dif_rv_core_ibex_error_status_t err_ibx;
1163 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1169 otbn_fi_loop_counter_t uj_output;
1170 uj_output.loop_counter = loop_counter;
1171 uj_output.err_otbn = err_otbn;
1172 uj_output.err_ibx = err_ibx;
1173 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1174 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1175 sizeof(sensor_alerts.alerts));
1176 RESP_OK(ujson_serialize_otbn_fi_loop_counter_t, uj, &uj_output);
1184 pentest_clear_sensor_recov_alerts();
1189 const otbn_app_t kOtbnAppCharUnrolledRegOpLoop =
1191 static const otbn_addr_t kOtbnAppCharUnrolledRegOpLoopLC =
1193 otbn_load_app(kOtbnAppCharUnrolledRegOpLoop);
1195 uint32_t loop_counter;
1198 pentest_set_trigger_high();
1200 otbn_busy_wait_for_done();
1201 pentest_set_trigger_low();
1203 reg_alerts = pentest_get_triggered_alerts();
1208 otbn_dmem_read(1, kOtbnAppCharUnrolledRegOpLoopLC, &loop_counter);
1212 read_otbn_err_bits(&err_otbn);
1215 dif_rv_core_ibex_error_status_t err_ibx;
1216 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1222 otbn_fi_loop_counter_t uj_output;
1223 uj_output.loop_counter = loop_counter;
1224 uj_output.err_otbn = err_otbn;
1225 uj_output.err_ibx = err_ibx;
1226 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1227 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1228 sizeof(sensor_alerts.alerts));
1229 RESP_OK(ujson_serialize_otbn_fi_loop_counter_t, uj, &uj_output);
1234 penetrationtest_cpuctrl_t uj_data;
1235 TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));
1239 TRY(pentest_configure_entropy_source_max_reseed_interval());
1241 pentest_select_trigger_type(kPentestTriggerTypeSw);
1242 pentest_init(kPentestTriggerSourceOtbn,
1243 kPentestPeripheralIoDiv4 | kPentestPeripheralEdn |
1244 kPentestPeripheralCsrng | kPentestPeripheralEntropy |
1245 kPentestPeripheralAes | kPentestPeripheralHmac |
1246 kPentestPeripheralKmac | kPentestPeripheralOtbn);
1249 TRY(dif_rv_core_ibex_init(
1258 pentest_configure_alert_handler();
1261 penetrationtest_device_info_t uj_output;
1262 TRY(pentest_configure_cpu(
1263 uj_data.icache_disable, uj_data.dummy_instr_disable,
1264 uj_data.enable_jittery_clock, uj_data.enable_sram_readback,
1265 &uj_output.clock_jitter_locked, &uj_output.clock_jitter_en,
1266 &uj_output.sram_main_readback_locked, &uj_output.sram_ret_readback_locked,
1267 &uj_output.sram_main_readback_en, &uj_output.sram_ret_readback_en));
1272 load_integrity_init =
false;
1273 key_sideloading_init =
false;
1274 char_mem_init =
false;
1275 char_mem_test_cfg_valid =
false;
1278 TRY(pentest_read_device_id(uj_output.device_id));
1279 RESP_OK(ujson_serialize_penetrationtest_device_info_t, uj, &uj_output);
1289 TRY(keymgr_testutils_initialize(&keymgr, &kmac));
1293 TRY(keymgr_testutils_generate_versioned_key(&keymgr, sideload_params));
1302 pentest_clear_sensor_recov_alerts();
1304 if (!key_sideloading_init) {
1306 otbn_load_app(kOtbnAppKeySideload);
1309 otbn_busy_wait_for_done();
1311 otbn_dmem_read(1, kOtbnAppKeySideloadks0l, &key_share_0_l_ref);
1312 otbn_dmem_read(1, kOtbnAppKeySideloadks0h, &key_share_0_h_ref);
1313 otbn_dmem_read(1, kOtbnAppKeySideloadks1l, &key_share_1_l_ref);
1314 otbn_dmem_read(1, kOtbnAppKeySideloadks1h, &key_share_1_h_ref);
1316 key_sideloading_init =
true;
1320 pentest_set_trigger_high();
1322 otbn_busy_wait_for_done();
1323 pentest_set_trigger_low();
1326 reg_alerts = pentest_get_triggered_alerts();
1331 uint32_t key_share_0_l, key_share_0_h;
1332 uint32_t key_share_1_l, key_share_1_h;
1333 otbn_dmem_read(1, kOtbnAppKeySideloadks0l, &key_share_0_l);
1334 otbn_dmem_read(1, kOtbnAppKeySideloadks0h, &key_share_0_h);
1335 otbn_dmem_read(1, kOtbnAppKeySideloadks1l, &key_share_1_l);
1336 otbn_dmem_read(1, kOtbnAppKeySideloadks1h, &key_share_1_h);
1340 read_otbn_err_bits(&err_otbn);
1343 dif_rv_core_ibex_error_status_t err_ibx;
1344 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1346 otbn_fi_keys_t uj_output;
1347 uj_output.keys[0] = key_share_0_l;
1348 uj_output.keys[1] = key_share_0_h;
1349 uj_output.keys[2] = key_share_1_l;
1350 uj_output.keys[3] = key_share_1_h;
1353 if ((key_share_0_l != key_share_0_l_ref) ||
1354 (key_share_0_h != key_share_0_h_ref) ||
1355 (key_share_1_l != key_share_1_l_ref) ||
1356 (key_share_1_h != key_share_1_h_ref)) {
1361 uj_output.err_otbn = err_otbn;
1362 uj_output.err_ibx = err_ibx;
1363 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1364 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1365 sizeof(sensor_alerts.alerts));
1366 RESP_OK(ujson_serialize_otbn_fi_keys_t, uj, &uj_output);
1374 pentest_clear_sensor_recov_alerts();
1376 if (!load_integrity_init) {
1379 clear_otbn_load_checksum();
1380 otbn_load_app(kOtbnAppLoadIntegrity);
1381 read_otbn_load_checksum(&load_checksum_ref);
1382 clear_otbn_load_checksum();
1384 load_integrity_init =
true;
1388 pentest_set_trigger_high();
1389 otbn_load_app(kOtbnAppLoadIntegrity);
1390 pentest_set_trigger_low();
1392 reg_alerts = pentest_get_triggered_alerts();
1397 uint32_t load_checksum;
1398 read_otbn_load_checksum(&load_checksum);
1399 clear_otbn_load_checksum();
1402 uint32_t ref_val1, ref_val2, ref_val3;
1403 otbn_dmem_read(1, kOtbnAppLoadIntegrityRefVal1, &ref_val1);
1404 otbn_dmem_read(1, kOtbnAppLoadIntegrityRefVal2, &ref_val2);
1405 otbn_dmem_read(1, kOtbnAppLoadIntegrityRefVal3, &ref_val3);
1408 bool dmem_corrupted =
false;
1409 if ((ref_val1 != 0x1BADB002) || (ref_val2 != 0x8BADF00D) ||
1410 (ref_val3 != 0xA5A5A5A5)) {
1411 dmem_corrupted =
true;
1417 if ((load_checksum_ref == load_checksum) && dmem_corrupted) {
1423 read_otbn_err_bits(&err_otbn);
1426 dif_rv_core_ibex_error_status_t err_ibx;
1427 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1433 otbn_fi_result_t uj_output;
1434 uj_output.result = res;
1435 uj_output.err_otbn = err_otbn;
1436 uj_output.err_ibx = err_ibx;
1437 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1438 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1439 sizeof(sensor_alerts.alerts));
1440 RESP_OK(ujson_serialize_otbn_fi_result_t, uj, &uj_output);
1446 otbn_fi_pc_t uj_data;
1447 TRY(ujson_deserialize_otbn_fi_pc_t(uj, &uj_data));
1452 pentest_clear_sensor_recov_alerts();
1464 otbn_load_app(kOtbnAppPc);
1467 pentest_set_trigger_high();
1471 bool is_running =
false;
1472 while (!is_running) {
1474 if (otbn_status != kDifOtbnStatusIdle) {
1478 pentest_set_trigger_low();
1479 otbn_busy_wait_for_done();
1481 reg_alerts = pentest_get_triggered_alerts();
1486 otbn_fi_pc_out_t uj_output;
1488 sizeof(uj_output.pc_otbn)));
1490 sizeof(uj_output.pc_dmem)));
1497 read_otbn_err_bits(&err_otbn);
1500 dif_rv_core_ibex_error_status_t err_ibx;
1501 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1507 uj_output.err_otbn = err_otbn;
1508 uj_output.err_ibx = err_ibx;
1509 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1510 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1511 sizeof(sensor_alerts.alerts));
1512 RESP_OK(ujson_serialize_otbn_fi_pc_out_t, uj, &uj_output);
1517 otbn_fi_subcommand_t cmd;
1518 TRY(ujson_deserialize_otbn_fi_subcommand_t(uj, &cmd));
1520 case kOtbnFiSubcommandCharBeq:
1521 return handle_otbn_fi_char_beq(uj);
1522 case kOtbnFiSubcommandCharBnRshi:
1523 return handle_otbn_fi_char_bn_rshi(uj);
1524 case kOtbnFiSubcommandCharBnSel:
1525 return handle_otbn_fi_char_bn_sel(uj);
1526 case kOtbnFiSubcommandCharBnWsrr:
1527 return handle_otbn_fi_char_bn_wsrr(uj);
1528 case kOtbnFiSubcommandCharBne:
1529 return handle_otbn_fi_char_bne(uj);
1530 case kOtbnFiSubcommandCharDmemAccess:
1531 return handle_otbn_fi_char_dmem_access(uj);
1532 case kOtbnFiSubcommandCharDmemWrite:
1533 return handle_otbn_fi_char_dmem_write(uj);
1534 case kOtbnFiSubcommandCharHardwareDmemOpLoop:
1535 return handle_otbn_fi_char_hardware_dmem_op_loop(uj);
1536 case kOtbnFiSubcommandCharHardwareRegOpLoop:
1537 return handle_otbn_fi_char_hardware_reg_op_loop(uj);
1538 case kOtbnFiSubcommandCharJal:
1539 return handle_otbn_fi_char_jal(uj);
1540 case kOtbnFiSubcommandCharLw:
1541 return handle_otbn_fi_char_lw(uj);
1542 case kOtbnFiSubcommandCharMem:
1543 return handle_otbn_fi_char_mem(uj);
1544 case kOtbnFiSubcommandCharRF:
1545 return handle_otbn_fi_char_register_file(uj);
1546 case kOtbnFiSubcommandCharUnrolledDmemOpLoop:
1547 return handle_otbn_fi_char_unrolled_dmem_op_loop(uj);
1548 case kOtbnFiSubcommandCharUnrolledRegOpLoop:
1549 return handle_otbn_fi_char_unrolled_reg_op_loop(uj);
1550 case kOtbnFiSubcommandInit:
1551 return handle_otbn_fi_init(uj);
1552 case kOtbnFiSubcommandInitKeyMgr:
1553 return handle_otbn_fi_init_keymgr(uj);
1554 case kOtbnFiSubcommandKeySideload:
1555 return handle_otbn_fi_key_sideload(uj);
1556 case kOtbnFiSubcommandLoadIntegrity:
1557 return handle_otbn_fi_load_integrity(uj);
1558 case kOtbnFiSubcommandPC:
1559 return handle_otbn_fi_pc(uj);
1561 LOG_ERROR(
"Unrecognized OTBN FI subcommand: %d", cmd);
1562 return INVALID_ARGUMENT();