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 static const uint32_t ref_values[32] = {
84 0x1BADB002, 0x8BADF00D, 0xA5A5A5A5, 0xABABABAB, 0xABBABABE, 0xABADCAFE,
85 0xBAAAAAAD, 0xBAD22222, 0xBBADBEEF, 0xBEBEBEBE, 0xBEEFCACE, 0xC00010FF,
86 0xCAFED00D, 0xCAFEFEED, 0xCCCCCCCC, 0xCDCDCDCD, 0x0D15EA5E, 0xDEAD10CC,
87 0xDEADBEEF, 0xDEADCAFE, 0xDEADC0DE, 0xDEADFA11, 0xDEADF00D, 0xDEFEC8ED,
88 0xDEADDEAD, 0xD00D2BAD, 0xEBEBEBEB, 0xFADEDEAD, 0xFDFDFDFD, 0xFEE1DEAD,
89 0xFEEDFACE, 0xFEEEFEEE};
114 TRY(otbn_dmem_sec_wipe());
115 TRY(otbn_imem_sec_wipe());
135 status_t read_otbn_load_checksum(uint32_t *checksum) {
143 status_t clear_otbn_load_checksum(
void) {
152 pentest_clear_sensor_recov_alerts();
158 static const otbn_addr_t kOtbnAppCharBeqRes =
160 otbn_load_app(kOtbnAppCharBeq);
163 pentest_set_trigger_high();
165 otbn_busy_wait_for_done();
166 pentest_set_trigger_low();
168 reg_alerts = pentest_get_triggered_alerts();
173 otbn_fi_result_cnt_t uj_output;
174 uj_output.result = 0;
175 otbn_dmem_read(1, kOtbnAppCharBeqRes, &uj_output.result);
182 read_otbn_err_bits(&err_otbn);
185 dif_rv_core_ibex_error_status_t err_ibx;
186 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
192 uj_output.err_otbn = err_otbn;
193 uj_output.err_ibx = err_ibx;
194 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
195 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
196 sizeof(sensor_alerts.alerts));
197 RESP_OK(ujson_serialize_otbn_fi_result_cnt_t, uj, &uj_output);
203 otbn_fi_big_num_t uj_data;
204 TRY(ujson_deserialize_otbn_fi_big_num_t(uj, &uj_data));
209 pentest_clear_sensor_recov_alerts();
216 static const otbn_addr_t kOtbnAppCharBnRshiBigNum =
218 static const otbn_addr_t kOtbnAppCharBnRshiBigNumOut =
222 otbn_load_app(kOtbnAppCharBnRshi);
224 sizeof(uj_data.big_num)));
227 pentest_set_trigger_high();
229 otbn_busy_wait_for_done();
230 pentest_set_trigger_low();
232 reg_alerts = pentest_get_triggered_alerts();
237 otbn_fi_big_num_out_t uj_output;
238 memset(uj_output.big_num, 0,
sizeof(uj_output.big_num));
240 sizeof(uj_output.big_num)));
247 read_otbn_err_bits(&err_otbn);
250 dif_rv_core_ibex_error_status_t err_ibx;
251 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
257 uj_output.err_otbn = err_otbn;
258 uj_output.err_ibx = err_ibx;
259 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
260 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
261 sizeof(sensor_alerts.alerts));
262 RESP_OK(ujson_serialize_otbn_fi_big_num_out_t, uj, &uj_output);
268 otbn_fi_big_num_t uj_data;
269 TRY(ujson_deserialize_otbn_fi_big_num_t(uj, &uj_data));
274 pentest_clear_sensor_recov_alerts();
281 static const otbn_addr_t kOtbnAppCharBnSelBigNum =
283 static const otbn_addr_t kOtbnAppCharBnSelBigNumOut =
287 otbn_load_app(kOtbnAppCharBnSel);
289 sizeof(uj_data.big_num)));
292 pentest_set_trigger_high();
294 otbn_busy_wait_for_done();
295 pentest_set_trigger_low();
297 reg_alerts = pentest_get_triggered_alerts();
302 otbn_fi_big_num_out_t uj_output;
303 memset(uj_output.big_num, 0,
sizeof(uj_output.big_num));
305 sizeof(uj_output.big_num)));
312 read_otbn_err_bits(&err_otbn);
315 dif_rv_core_ibex_error_status_t err_ibx;
316 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
322 uj_output.err_otbn = err_otbn;
323 uj_output.err_ibx = err_ibx;
324 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
325 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
326 sizeof(sensor_alerts.alerts));
327 RESP_OK(ujson_serialize_otbn_fi_big_num_out_t, uj, &uj_output);
335 pentest_clear_sensor_recov_alerts();
341 static const otbn_addr_t kOtbnAppCharBnWsrrResValuesWDR =
345 otbn_load_app(kOtbnAppCharBnWsrr);
348 pentest_set_trigger_high();
350 otbn_busy_wait_for_done();
351 pentest_set_trigger_low();
354 reg_alerts = pentest_get_triggered_alerts();
360 read_otbn_err_bits(&err_otbn);
363 dif_rv_core_ibex_error_status_t err_ibx;
364 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
367 otbn_fi_data_t uj_output;
369 memset(uj_output.data, 0,
sizeof(uj_output.data));
371 sizeof(uj_output.data)));
379 uj_output.err_otbn = err_otbn;
380 uj_output.err_ibx = err_ibx;
381 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
382 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
383 sizeof(sensor_alerts.alerts));
384 RESP_OK(ujson_serialize_otbn_fi_data_t, uj, &uj_output);
393 pentest_clear_sensor_recov_alerts();
399 static const otbn_addr_t kOtbnAppCharBneRes =
401 otbn_load_app(kOtbnAppCharBne);
404 pentest_set_trigger_high();
406 otbn_busy_wait_for_done();
407 pentest_set_trigger_low();
410 reg_alerts = pentest_get_triggered_alerts();
414 otbn_fi_result_cnt_t uj_output;
415 uj_output.result = 0;
416 otbn_dmem_read(1, kOtbnAppCharBneRes, &uj_output.result);
423 read_otbn_err_bits(&err_otbn);
426 dif_rv_core_ibex_error_status_t err_ibx;
427 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
432 uj_output.err_otbn = err_otbn;
433 uj_output.err_ibx = err_ibx;
434 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
435 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
436 sizeof(sensor_alerts.alerts));
437 RESP_OK(ujson_serialize_otbn_fi_result_cnt_t, uj, &uj_output);
445 pentest_clear_sensor_recov_alerts();
450 static const otbn_app_t kOtbnAppCharDmemAccess =
452 static const otbn_addr_t kOtbnVarCharDmemAccessValues =
455 otbn_load_app(kOtbnAppCharDmemAccess);
458 pentest_set_trigger_high();
460 otbn_busy_wait_for_done();
461 pentest_set_trigger_low();
464 reg_alerts = pentest_get_triggered_alerts();
470 read_otbn_err_bits(&err_otbn);
473 dif_rv_core_ibex_error_status_t err_ibx;
474 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
477 otbn_fi_data_t uj_output;
479 memset(uj_output.data, 0,
sizeof(uj_output.data));
481 sizeof(uj_output.data)));
486 uj_output.err_otbn = err_otbn;
487 uj_output.err_ibx = err_ibx;
488 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
489 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
490 sizeof(sensor_alerts.alerts));
491 RESP_OK(ujson_serialize_otbn_fi_data_t, uj, &uj_output);
500 pentest_clear_sensor_recov_alerts();
506 static const otbn_app_t kOtbnAppCharDmemWrite =
508 static const otbn_addr_t kOtbnVarCharDmemWriteMem =
512 otbn_load_app(kOtbnAppCharDmemWrite);
514 pentest_set_trigger_high();
519 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem),
523 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 4),
527 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 8),
531 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 12),
535 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 16),
539 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 20),
543 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 24),
547 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 28),
551 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 32),
555 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 36),
559 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 40),
563 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 44),
567 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 48),
571 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 52),
575 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 56),
579 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 60),
583 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 64),
587 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 68),
591 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 72),
595 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 76),
599 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 80),
603 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 84),
607 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 88),
611 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 92),
615 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 96),
619 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 100),
623 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 104),
627 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 108),
631 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 112),
635 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 116),
639 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 120),
643 (ptrdiff_t)(OTBN_DMEM_REG_OFFSET + kOtbnVarCharDmemWriteMem + 124),
646 pentest_set_trigger_low();
650 otbn_busy_wait_for_done();
653 reg_alerts = pentest_get_triggered_alerts();
659 read_otbn_err_bits(&err_otbn);
662 dif_rv_core_ibex_error_status_t err_ibx;
663 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
666 otbn_fi_result_array_t uj_output;
667 uint32_t res_values[
ARRAYSIZE(ref_values)];
668 memset(res_values, 0,
sizeof(res_values));
670 sizeof(res_values)));
671 for (
size_t it = 0; it <
ARRAYSIZE(ref_values); it++) {
672 uj_output.result[it] = res_values[it] ^ ref_values[it];
682 uj_output.err_otbn = err_otbn;
683 uj_output.err_ibx = err_ibx;
684 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
685 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
686 sizeof(sensor_alerts.alerts));
687 RESP_OK(ujson_serialize_otbn_fi_result_array_t, uj, &uj_output);
696 pentest_clear_sensor_recov_alerts();
701 const otbn_app_t kOtbnAppCharHardwareDmemOpLoop =
703 static const otbn_addr_t kOtbnAppCharHardwareDmemOpLoopLC =
705 otbn_load_app(kOtbnAppCharHardwareDmemOpLoop);
707 uint32_t loop_counter;
710 pentest_set_trigger_high();
712 otbn_busy_wait_for_done();
713 pentest_set_trigger_low();
715 reg_alerts = pentest_get_triggered_alerts();
720 otbn_dmem_read(1, kOtbnAppCharHardwareDmemOpLoopLC, &loop_counter);
724 read_otbn_err_bits(&err_otbn);
727 dif_rv_core_ibex_error_status_t err_ibx;
728 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
734 otbn_fi_loop_counter_t uj_output;
735 uj_output.loop_counter = loop_counter;
736 uj_output.err_otbn = err_otbn;
737 uj_output.err_ibx = err_ibx;
738 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
739 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
740 sizeof(sensor_alerts.alerts));
741 RESP_OK(ujson_serialize_otbn_fi_loop_counter_t, uj, &uj_output);
749 pentest_clear_sensor_recov_alerts();
754 const otbn_app_t kOtbnAppCharHardwareRegOpLoop =
756 static const otbn_addr_t kOtbnAppCharHardwareRegOpLoopLC =
758 otbn_load_app(kOtbnAppCharHardwareRegOpLoop);
760 uint32_t loop_counter;
763 pentest_set_trigger_high();
765 otbn_busy_wait_for_done();
766 pentest_set_trigger_low();
768 reg_alerts = pentest_get_triggered_alerts();
773 otbn_dmem_read(1, kOtbnAppCharHardwareRegOpLoopLC, &loop_counter);
777 read_otbn_err_bits(&err_otbn);
780 dif_rv_core_ibex_error_status_t err_ibx;
781 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
787 otbn_fi_loop_counter_t uj_output;
788 uj_output.loop_counter = loop_counter;
789 uj_output.err_otbn = err_otbn;
790 uj_output.err_ibx = err_ibx;
791 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
792 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
793 sizeof(sensor_alerts.alerts));
794 RESP_OK(ujson_serialize_otbn_fi_loop_counter_t, uj, &uj_output);
802 pentest_clear_sensor_recov_alerts();
808 static const otbn_addr_t kOtbnAppCharJalRes =
810 otbn_load_app(kOtbnAppCharJal);
813 pentest_set_trigger_high();
815 otbn_busy_wait_for_done();
816 pentest_set_trigger_low();
818 reg_alerts = pentest_get_triggered_alerts();
823 otbn_fi_result_cnt_t uj_output;
824 uj_output.result = 0;
825 otbn_dmem_read(1, kOtbnAppCharJalRes, &uj_output.result);
832 read_otbn_err_bits(&err_otbn);
835 dif_rv_core_ibex_error_status_t err_ibx;
836 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
842 uj_output.err_otbn = err_otbn;
843 uj_output.err_ibx = err_ibx;
844 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
845 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
846 sizeof(sensor_alerts.alerts));
847 RESP_OK(ujson_serialize_otbn_fi_result_cnt_t, uj, &uj_output);
855 pentest_clear_sensor_recov_alerts();
862 static const otbn_addr_t kOtbnMemIn =
OTBN_ADDR_T_INIT(otbn_char_lw, mem_in);
863 static const otbn_addr_t kOtbnMemOut =
867 otbn_load_app(kOtbnAppCharLw);
871 pentest_set_trigger_high();
873 otbn_busy_wait_for_done();
874 pentest_set_trigger_low();
877 reg_alerts = pentest_get_triggered_alerts();
882 otbn_fi_result_array_t uj_output;
883 uint32_t res_values[29];
884 memset(res_values, 0,
sizeof(res_values));
885 memset(uj_output.result, 0,
sizeof(uj_output.result));
887 for (
size_t it = 0; it < 29; it++) {
888 uj_output.result[it] = res_values[it] ^ ref_values[it];
896 read_otbn_err_bits(&err_otbn);
899 dif_rv_core_ibex_error_status_t err_ibx;
900 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
906 uj_output.err_otbn = err_otbn;
907 uj_output.err_ibx = err_ibx;
908 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
909 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
910 sizeof(sensor_alerts.alerts));
911 RESP_OK(ujson_serialize_otbn_fi_result_array_t, uj, &uj_output);
918 if (!char_mem_test_cfg_valid) {
919 otbn_fi_mem_cfg_t uj_cfg;
920 TRY(ujson_deserialize_otbn_fi_mem_cfg_t(uj, &uj_cfg));
921 char_mem_imem = uj_cfg.imem;
922 char_mem_dmem = uj_cfg.dmem;
923 char_mem_byte_offset = uj_cfg.byte_offset;
924 char_mem_num_words = uj_cfg.num_words;
926 char_mem_test_cfg_valid =
true;
932 pentest_clear_sensor_recov_alerts();
935 uint32_t dmem_array_ref[char_mem_num_words];
936 uint32_t imem_array_ref[char_mem_num_words];
938 memset(dmem_array_ref, 0xab,
sizeof(dmem_array_ref));
941 memset(imem_array_ref, 0xdf,
sizeof(imem_array_ref));
944 if (!char_mem_init) {
947 sizeof(dmem_array_ref)));
951 sizeof(imem_array_ref)));
953 char_mem_init =
true;
957 pentest_set_trigger_high();
958 asm volatile(NOP100);
959 pentest_set_trigger_low();
962 reg_alerts = pentest_get_triggered_alerts();
968 read_otbn_err_bits(&err_otbn);
971 dif_rv_core_ibex_error_status_t err_ibx;
972 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
974 otbn_fi_mem_t uj_output;
976 memset(uj_output.dmem_data, 0,
sizeof(uj_output.dmem_data));
977 memset(uj_output.dmem_addr, 0,
sizeof(uj_output.dmem_addr));
978 memset(uj_output.imem_data, 0,
sizeof(uj_output.imem_data));
979 memset(uj_output.imem_addr, 0,
sizeof(uj_output.imem_addr));
983 size_t fault_pos = 0;
985 uint32_t dmem_array_res[char_mem_num_words];
987 sizeof(dmem_array_ref)));
988 for (
size_t it = 0; it < char_mem_num_words; it++) {
989 if (dmem_array_res[it] != dmem_array_ref[it] &&
990 fault_pos <
ARRAYSIZE(uj_output.dmem_data)) {
991 uj_output.dmem_data[fault_pos] = dmem_array_res[it];
992 uj_output.dmem_addr[fault_pos] = it;
995 char_mem_init =
false;
1002 uint32_t imem_array_res[char_mem_num_words];
1003 if (char_mem_imem) {
1005 sizeof(imem_array_ref)));
1007 for (
size_t it = 0; it < char_mem_num_words; it++) {
1008 if (imem_array_res[it] != imem_array_ref[it] &&
1009 fault_pos <
ARRAYSIZE(uj_output.imem_data)) {
1010 uj_output.imem_data[fault_pos] = imem_array_res[it];
1011 uj_output.imem_addr[fault_pos] = it;
1014 char_mem_init =
false;
1021 uj_output.err_otbn = err_otbn;
1022 uj_output.err_ibx = err_ibx;
1023 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1024 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1025 sizeof(sensor_alerts.alerts));
1026 RESP_OK(ujson_serialize_otbn_fi_mem_t, uj, &uj_output);
1035 pentest_clear_sensor_recov_alerts();
1044 static const otbn_addr_t kOtbnVarCharRFRefValues =
1046 static const otbn_addr_t kOtbnVarCharRFResValuesGPR =
1048 static const otbn_addr_t kOtbnVarCharRFResValuesWDR =
1052 otbn_load_app(kOtbnAppCharRF);
1054 sizeof(ref_values)));
1056 pentest_set_trigger_high();
1058 otbn_busy_wait_for_done();
1059 pentest_set_trigger_low();
1062 reg_alerts = pentest_get_triggered_alerts();
1068 read_otbn_err_bits(&err_otbn);
1071 dif_rv_core_ibex_error_status_t err_ibx;
1072 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1075 uint32_t res_values_gpr[29];
1076 memset(res_values_gpr, 0,
sizeof(res_values_gpr));
1078 sizeof(res_values_gpr)));
1081 otbn_fi_rf_char_t uj_output;
1082 memset(uj_output.faulty_gpr, 0,
sizeof(uj_output.faulty_gpr));
1084 for (
size_t it = 0; it <
ARRAYSIZE(res_values_gpr); it++) {
1085 if (res_values_gpr[it] != ref_values[it]) {
1089 uj_output.faulty_gpr[it] = res_values_gpr[it] ^ ref_values[it];
1094 uint32_t res_values_wdr[256];
1095 memset(res_values_wdr, 0,
sizeof(res_values_wdr));
1097 sizeof(res_values_wdr)));
1100 memset(uj_output.faulty_wdr, 0,
sizeof(uj_output.faulty_wdr));
1101 for (
size_t it = 0; it <
ARRAYSIZE(res_values_wdr); it++) {
1102 if (res_values_wdr[it] != ref_values[it % 32]) {
1106 uj_output.faulty_wdr[it] = res_values_wdr[it] ^ ref_values[it % 32];
1111 uj_output.err_otbn = err_otbn;
1112 uj_output.err_ibx = err_ibx;
1113 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1114 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1115 sizeof(sensor_alerts.alerts));
1116 RESP_OK(ujson_serialize_otbn_fi_rf_char_t, uj, &uj_output);
1125 pentest_clear_sensor_recov_alerts();
1130 const otbn_app_t kOtbnAppCharUnrolledDmemOpLoop =
1132 static const otbn_addr_t kOtbnAppCharUnrolledDmemOpLoopLC =
1134 otbn_load_app(kOtbnAppCharUnrolledDmemOpLoop);
1136 uint32_t loop_counter;
1139 pentest_set_trigger_high();
1141 otbn_busy_wait_for_done();
1142 pentest_set_trigger_low();
1144 reg_alerts = pentest_get_triggered_alerts();
1149 otbn_dmem_read(1, kOtbnAppCharUnrolledDmemOpLoopLC, &loop_counter);
1153 read_otbn_err_bits(&err_otbn);
1156 dif_rv_core_ibex_error_status_t err_ibx;
1157 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1163 otbn_fi_loop_counter_t uj_output;
1164 uj_output.loop_counter = loop_counter;
1165 uj_output.err_otbn = err_otbn;
1166 uj_output.err_ibx = err_ibx;
1167 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1168 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1169 sizeof(sensor_alerts.alerts));
1170 RESP_OK(ujson_serialize_otbn_fi_loop_counter_t, uj, &uj_output);
1178 pentest_clear_sensor_recov_alerts();
1183 const otbn_app_t kOtbnAppCharUnrolledRegOpLoop =
1185 static const otbn_addr_t kOtbnAppCharUnrolledRegOpLoopLC =
1187 otbn_load_app(kOtbnAppCharUnrolledRegOpLoop);
1189 uint32_t loop_counter;
1192 pentest_set_trigger_high();
1194 otbn_busy_wait_for_done();
1195 pentest_set_trigger_low();
1197 reg_alerts = pentest_get_triggered_alerts();
1202 otbn_dmem_read(1, kOtbnAppCharUnrolledRegOpLoopLC, &loop_counter);
1206 read_otbn_err_bits(&err_otbn);
1209 dif_rv_core_ibex_error_status_t err_ibx;
1210 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1216 otbn_fi_loop_counter_t uj_output;
1217 uj_output.loop_counter = loop_counter;
1218 uj_output.err_otbn = err_otbn;
1219 uj_output.err_ibx = err_ibx;
1220 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1221 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1222 sizeof(sensor_alerts.alerts));
1223 RESP_OK(ujson_serialize_otbn_fi_loop_counter_t, uj, &uj_output);
1228 penetrationtest_cpuctrl_t uj_data;
1229 TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));
1233 TRY(pentest_configure_entropy_source_max_reseed_interval());
1235 pentest_select_trigger_type(kPentestTriggerTypeSw);
1236 pentest_init(kPentestTriggerSourceOtbn,
1237 kPentestPeripheralIoDiv4 | kPentestPeripheralEdn |
1238 kPentestPeripheralCsrng | kPentestPeripheralEntropy |
1239 kPentestPeripheralAes | kPentestPeripheralHmac |
1240 kPentestPeripheralKmac | kPentestPeripheralOtbn);
1243 TRY(dif_rv_core_ibex_init(
1252 pentest_configure_alert_handler();
1255 penetrationtest_device_info_t uj_output;
1256 TRY(pentest_configure_cpu(
1257 uj_data.icache_disable, uj_data.dummy_instr_disable,
1258 uj_data.enable_jittery_clock, uj_data.enable_sram_readback,
1259 &uj_output.clock_jitter_locked, &uj_output.clock_jitter_en,
1260 &uj_output.sram_main_readback_locked, &uj_output.sram_ret_readback_locked,
1261 &uj_output.sram_main_readback_en, &uj_output.sram_ret_readback_en));
1266 load_integrity_init =
false;
1267 key_sideloading_init =
false;
1268 char_mem_init =
false;
1269 char_mem_test_cfg_valid =
false;
1272 TRY(pentest_read_device_id(uj_output.device_id));
1273 RESP_OK(ujson_serialize_penetrationtest_device_info_t, uj, &uj_output);
1283 TRY(keymgr_testutils_initialize(&keymgr, &kmac));
1287 TRY(keymgr_testutils_generate_versioned_key(&keymgr, sideload_params));
1296 pentest_clear_sensor_recov_alerts();
1298 if (!key_sideloading_init) {
1300 otbn_load_app(kOtbnAppKeySideload);
1303 otbn_busy_wait_for_done();
1305 otbn_dmem_read(1, kOtbnAppKeySideloadks0l, &key_share_0_l_ref);
1306 otbn_dmem_read(1, kOtbnAppKeySideloadks0h, &key_share_0_h_ref);
1307 otbn_dmem_read(1, kOtbnAppKeySideloadks1l, &key_share_1_l_ref);
1308 otbn_dmem_read(1, kOtbnAppKeySideloadks1h, &key_share_1_h_ref);
1310 key_sideloading_init =
true;
1314 pentest_set_trigger_high();
1316 otbn_busy_wait_for_done();
1317 pentest_set_trigger_low();
1320 reg_alerts = pentest_get_triggered_alerts();
1325 uint32_t key_share_0_l, key_share_0_h;
1326 uint32_t key_share_1_l, key_share_1_h;
1327 otbn_dmem_read(1, kOtbnAppKeySideloadks0l, &key_share_0_l);
1328 otbn_dmem_read(1, kOtbnAppKeySideloadks0h, &key_share_0_h);
1329 otbn_dmem_read(1, kOtbnAppKeySideloadks1l, &key_share_1_l);
1330 otbn_dmem_read(1, kOtbnAppKeySideloadks1h, &key_share_1_h);
1334 read_otbn_err_bits(&err_otbn);
1337 dif_rv_core_ibex_error_status_t err_ibx;
1338 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1340 otbn_fi_keys_t uj_output;
1341 uj_output.keys[0] = key_share_0_l;
1342 uj_output.keys[1] = key_share_0_h;
1343 uj_output.keys[2] = key_share_1_l;
1344 uj_output.keys[3] = key_share_1_h;
1347 if ((key_share_0_l != key_share_0_l_ref) ||
1348 (key_share_0_h != key_share_0_h_ref) ||
1349 (key_share_1_l != key_share_1_l_ref) ||
1350 (key_share_1_h != key_share_1_h_ref)) {
1355 uj_output.err_otbn = err_otbn;
1356 uj_output.err_ibx = err_ibx;
1357 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1358 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1359 sizeof(sensor_alerts.alerts));
1360 RESP_OK(ujson_serialize_otbn_fi_keys_t, uj, &uj_output);
1368 pentest_clear_sensor_recov_alerts();
1370 if (!load_integrity_init) {
1373 clear_otbn_load_checksum();
1374 otbn_load_app(kOtbnAppLoadIntegrity);
1375 read_otbn_load_checksum(&load_checksum_ref);
1376 clear_otbn_load_checksum();
1378 load_integrity_init =
true;
1382 pentest_set_trigger_high();
1383 otbn_load_app(kOtbnAppLoadIntegrity);
1384 pentest_set_trigger_low();
1386 reg_alerts = pentest_get_triggered_alerts();
1391 uint32_t load_checksum;
1392 read_otbn_load_checksum(&load_checksum);
1393 clear_otbn_load_checksum();
1396 uint32_t ref_val1, ref_val2, ref_val3;
1397 otbn_dmem_read(1, kOtbnAppLoadIntegrityRefVal1, &ref_val1);
1398 otbn_dmem_read(1, kOtbnAppLoadIntegrityRefVal2, &ref_val2);
1399 otbn_dmem_read(1, kOtbnAppLoadIntegrityRefVal3, &ref_val3);
1402 bool dmem_corrupted =
false;
1403 if ((ref_val1 != 0x1BADB002) || (ref_val2 != 0x8BADF00D) ||
1404 (ref_val3 != 0xA5A5A5A5)) {
1405 dmem_corrupted =
true;
1411 if ((load_checksum_ref == load_checksum) && dmem_corrupted) {
1417 read_otbn_err_bits(&err_otbn);
1420 dif_rv_core_ibex_error_status_t err_ibx;
1421 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1427 otbn_fi_result_t uj_output;
1428 uj_output.result = res;
1429 uj_output.err_otbn = err_otbn;
1430 uj_output.err_ibx = err_ibx;
1431 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1432 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1433 sizeof(sensor_alerts.alerts));
1434 RESP_OK(ujson_serialize_otbn_fi_result_t, uj, &uj_output);
1440 otbn_fi_pc_t uj_data;
1441 TRY(ujson_deserialize_otbn_fi_pc_t(uj, &uj_data));
1446 pentest_clear_sensor_recov_alerts();
1458 otbn_load_app(kOtbnAppPc);
1461 pentest_set_trigger_high();
1465 bool is_running =
false;
1466 while (!is_running) {
1468 if (otbn_status != kDifOtbnStatusIdle) {
1472 pentest_set_trigger_low();
1473 otbn_busy_wait_for_done();
1475 reg_alerts = pentest_get_triggered_alerts();
1480 otbn_fi_pc_out_t uj_output;
1482 sizeof(uj_output.pc_otbn)));
1484 sizeof(uj_output.pc_dmem)));
1491 read_otbn_err_bits(&err_otbn);
1494 dif_rv_core_ibex_error_status_t err_ibx;
1495 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
1501 uj_output.err_otbn = err_otbn;
1502 uj_output.err_ibx = err_ibx;
1503 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
1504 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
1505 sizeof(sensor_alerts.alerts));
1506 RESP_OK(ujson_serialize_otbn_fi_pc_out_t, uj, &uj_output);
1511 otbn_fi_subcommand_t cmd;
1512 TRY(ujson_deserialize_otbn_fi_subcommand_t(uj, &cmd));
1514 case kOtbnFiSubcommandCharBeq:
1515 return handle_otbn_fi_char_beq(uj);
1516 case kOtbnFiSubcommandCharBnRshi:
1517 return handle_otbn_fi_char_bn_rshi(uj);
1518 case kOtbnFiSubcommandCharBnSel:
1519 return handle_otbn_fi_char_bn_sel(uj);
1520 case kOtbnFiSubcommandCharBnWsrr:
1521 return handle_otbn_fi_char_bn_wsrr(uj);
1522 case kOtbnFiSubcommandCharBne:
1523 return handle_otbn_fi_char_bne(uj);
1524 case kOtbnFiSubcommandCharDmemAccess:
1525 return handle_otbn_fi_char_dmem_access(uj);
1526 case kOtbnFiSubcommandCharDmemWrite:
1527 return handle_otbn_fi_char_dmem_write(uj);
1528 case kOtbnFiSubcommandCharHardwareDmemOpLoop:
1529 return handle_otbn_fi_char_hardware_dmem_op_loop(uj);
1530 case kOtbnFiSubcommandCharHardwareRegOpLoop:
1531 return handle_otbn_fi_char_hardware_reg_op_loop(uj);
1532 case kOtbnFiSubcommandCharJal:
1533 return handle_otbn_fi_char_jal(uj);
1534 case kOtbnFiSubcommandCharLw:
1535 return handle_otbn_fi_char_lw(uj);
1536 case kOtbnFiSubcommandCharMem:
1537 return handle_otbn_fi_char_mem(uj);
1538 case kOtbnFiSubcommandCharRF:
1539 return handle_otbn_fi_char_register_file(uj);
1540 case kOtbnFiSubcommandCharUnrolledDmemOpLoop:
1541 return handle_otbn_fi_char_unrolled_dmem_op_loop(uj);
1542 case kOtbnFiSubcommandCharUnrolledRegOpLoop:
1543 return handle_otbn_fi_char_unrolled_reg_op_loop(uj);
1544 case kOtbnFiSubcommandInit:
1545 return handle_otbn_fi_init(uj);
1546 case kOtbnFiSubcommandInitKeyMgr:
1547 return handle_otbn_fi_init_keymgr(uj);
1548 case kOtbnFiSubcommandKeySideload:
1549 return handle_otbn_fi_key_sideload(uj);
1550 case kOtbnFiSubcommandLoadIntegrity:
1551 return handle_otbn_fi_load_integrity(uj);
1552 case kOtbnFiSubcommandPC:
1553 return handle_otbn_fi_pc(uj);
1555 LOG_ERROR(
"Unrecognized OTBN FI subcommand: %d", cmd);
1556 return INVALID_ARGUMENT();