5 #include "sw/device/tests/penetrationtests/firmware/fi/otp_fi.h"
8 #include "sw/device/lib/base/status.h"
11 #include "sw/device/lib/testing/otp_ctrl_testutils.h"
12 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
13 #include "sw/device/lib/ujson/ujson.h"
14 #include "sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h"
15 #include "sw/device/tests/penetrationtests/json/otp_fi_commands.h"
18 #include "otp_ctrl_regs.h"
21 #define NOP1 "addi x0, x0, 0\n"
22 #define NOP10 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1
23 #define NOP100 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10 NOP10
25 NOP100 NOP100 NOP100 NOP100 NOP100 NOP100 NOP100 NOP100 NOP100 NOP100
27 static dif_otp_ctrl_t otp;
30 otp_read32_result_vendor_test_comp[OTP_CTRL_PARAM_VENDOR_TEST_SIZE / 4];
31 uint32_t otp_read32_result_vendor_test_fi[OTP_CTRL_PARAM_VENDOR_TEST_SIZE / 4];
33 otp_read32_result_owner_sw_cfg_comp[OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE / 4];
35 otp_read32_result_owner_sw_cfg_fi[OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE / 4];
36 uint32_t otp_read32_result_hw_cfg_comp[OTP_CTRL_PARAM_HW_CFG0_SIZE / 4];
37 uint32_t otp_read32_result_hw_cfg_fi[OTP_CTRL_PARAM_HW_CFG0_SIZE / 4];
38 uint32_t otp_read32_result_life_cycle_comp[OTP_CTRL_PARAM_LIFE_CYCLE_SIZE / 4];
39 uint32_t otp_read32_result_life_cycle_fi[OTP_CTRL_PARAM_LIFE_CYCLE_SIZE / 4];
41 void init_otp_mem_dump_buffers(
void) {
42 for (uint32_t i = 0; i < OTP_CTRL_PARAM_VENDOR_TEST_SIZE / 4; i++) {
43 otp_read32_result_vendor_test_comp[i] = 0x00000001;
44 otp_read32_result_vendor_test_fi[i] = 0x00000001;
46 for (uint32_t i = 0; i < OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE / 4; i++) {
47 otp_read32_result_owner_sw_cfg_comp[i] = 0x00000001;
48 otp_read32_result_owner_sw_cfg_fi[i] = 0x00000001;
50 for (uint32_t i = 0; i < OTP_CTRL_PARAM_HW_CFG0_SIZE / 4; i++) {
51 otp_read32_result_hw_cfg_comp[i] = 0x00000001;
52 otp_read32_result_hw_cfg_fi[i] = 0x00000001;
54 for (uint32_t i = 0; i < OTP_CTRL_PARAM_LIFE_CYCLE_SIZE / 4; i++) {
55 otp_read32_result_life_cycle_comp[i] = 0x00000001;
56 otp_read32_result_life_cycle_fi[i] = 0x00000001;
60 status_t otp_vendor_test_dump(uint32_t *buffer) {
64 OTP_CTRL_PARAM_VENDOR_TEST_SIZE / 4));
69 status_t otp_owner_sw_cfg_dump(uint32_t *buffer) {
71 TRY(otp_ctrl_testutils_dai_read32_array(
73 OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE / 4));
78 status_t otp_hw_cfg_dump(uint32_t *buffer) {
82 OTP_CTRL_PARAM_HW_CFG0_SIZE / 4));
87 status_t otp_life_cycle_dump(uint32_t *buffer) {
91 OTP_CTRL_PARAM_LIFE_CYCLE_SIZE / 4));
100 pentest_clear_sensor_recov_alerts();
103 TRY(otp_hw_cfg_dump(otp_read32_result_hw_cfg_comp));
106 pentest_set_trigger_high();
109 asm volatile(NOP1000);
110 asm volatile(NOP1000);
111 asm volatile(NOP1000);
112 asm volatile(NOP1000);
114 pentest_set_trigger_low();
117 TRY(otp_hw_cfg_dump(otp_read32_result_hw_cfg_fi));
120 reg_alerts = pentest_get_triggered_alerts();
129 otp_fi_hwcfg_partition_t uj_output;
130 for (uint32_t i = 0; i < OTP_CTRL_PARAM_HW_CFG0_SIZE / 4; i++) {
131 uj_output.hw_cfg_comp[i] = otp_read32_result_hw_cfg_comp[i];
132 uj_output.hw_cfg_fi[i] = otp_read32_result_hw_cfg_fi[i];
134 uj_output.otp_status_codes =
status.codes;
135 memcpy(uj_output.otp_error_causes, (uint8_t *)
status.causes,
137 uj_output.alerts[0] = reg_alerts.alerts[0];
138 uj_output.alerts[1] = reg_alerts.alerts[1];
139 uj_output.alerts[2] = reg_alerts.alerts[2];
140 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
141 sizeof(sensor_alerts.alerts));
142 RESP_OK(ujson_serialize_otp_fi_hwcfg_partition_t, uj, &uj_output);
148 penetrationtest_cpuctrl_t uj_data;
149 TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));
151 pentest_select_trigger_type(kPentestTriggerTypeSw);
155 pentest_init(kPentestTriggerSourceAes,
156 kPentestPeripheralIoDiv4 | kPentestPeripheralEdn |
157 kPentestPeripheralCsrng | kPentestPeripheralEntropy |
158 kPentestPeripheralAes | kPentestPeripheralHmac |
159 kPentestPeripheralKmac | kPentestPeripheralOtbn);
163 pentest_configure_alert_handler();
166 penetrationtest_device_info_t uj_output;
167 TRY(pentest_configure_cpu(
168 uj_data.icache_disable, uj_data.dummy_instr_disable,
169 uj_data.enable_jittery_clock, uj_data.enable_sram_readback,
170 &uj_output.clock_jitter_locked, &uj_output.clock_jitter_en,
171 &uj_output.sram_main_readback_locked, &uj_output.sram_ret_readback_locked,
172 &uj_output.sram_main_readback_en, &uj_output.sram_ret_readback_en));
174 TRY(dif_otp_ctrl_init(
177 init_otp_mem_dump_buffers();
180 TRY(pentest_read_device_id(uj_output.device_id));
181 RESP_OK(ujson_serialize_penetrationtest_device_info_t, uj, &uj_output);
190 pentest_clear_sensor_recov_alerts();
193 TRY(otp_life_cycle_dump(otp_read32_result_life_cycle_comp));
196 pentest_set_trigger_high();
199 asm volatile(NOP1000);
200 asm volatile(NOP1000);
201 asm volatile(NOP1000);
202 asm volatile(NOP1000);
204 pentest_set_trigger_low();
207 TRY(otp_life_cycle_dump(otp_read32_result_life_cycle_fi));
210 reg_alerts = pentest_get_triggered_alerts();
219 otp_fi_lifecycle_partition_t uj_output;
220 for (uint32_t i = 0; i < OTP_CTRL_PARAM_LIFE_CYCLE_SIZE / 4; i++) {
221 uj_output.life_cycle_comp[i] = otp_read32_result_life_cycle_comp[i];
222 uj_output.life_cycle_fi[i] = otp_read32_result_life_cycle_fi[i];
224 uj_output.otp_status_codes =
status.codes;
225 memcpy(uj_output.otp_error_causes, (uint8_t *)
status.causes,
227 uj_output.alerts[0] = reg_alerts.alerts[0];
228 uj_output.alerts[1] = reg_alerts.alerts[1];
229 uj_output.alerts[2] = reg_alerts.alerts[2];
230 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
231 sizeof(sensor_alerts.alerts));
232 RESP_OK(ujson_serialize_otp_fi_lifecycle_partition_t, uj, &uj_output);
241 pentest_clear_sensor_recov_alerts();
244 TRY(otp_owner_sw_cfg_dump(otp_read32_result_owner_sw_cfg_comp));
247 pentest_set_trigger_high();
250 asm volatile(NOP1000);
251 asm volatile(NOP1000);
252 asm volatile(NOP1000);
253 asm volatile(NOP1000);
255 pentest_set_trigger_low();
258 TRY(otp_owner_sw_cfg_dump(otp_read32_result_owner_sw_cfg_fi));
261 reg_alerts = pentest_get_triggered_alerts();
270 otp_fi_ownerswcfg_partition_t uj_output;
271 for (uint32_t i = 0; i < OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE / 4; i++) {
272 uj_output.owner_sw_cfg_comp[i] = otp_read32_result_owner_sw_cfg_comp[i];
273 uj_output.owner_sw_cfg_fi[i] = otp_read32_result_owner_sw_cfg_fi[i];
275 uj_output.otp_status_codes =
status.codes;
276 memcpy(uj_output.otp_error_causes, (uint8_t *)
status.causes,
278 uj_output.alerts[0] = reg_alerts.alerts[0];
279 uj_output.alerts[1] = reg_alerts.alerts[1];
280 uj_output.alerts[2] = reg_alerts.alerts[2];
281 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
282 sizeof(sensor_alerts.alerts));
283 RESP_OK(ujson_serialize_otp_fi_ownerswcfg_partition_t, uj, &uj_output);
292 pentest_clear_sensor_recov_alerts();
295 TRY(otp_vendor_test_dump(otp_read32_result_vendor_test_comp));
298 pentest_set_trigger_high();
301 asm volatile(NOP1000);
302 asm volatile(NOP1000);
303 asm volatile(NOP1000);
304 asm volatile(NOP1000);
306 pentest_set_trigger_low();
309 TRY(otp_vendor_test_dump(otp_read32_result_vendor_test_fi));
312 reg_alerts = pentest_get_triggered_alerts();
321 otp_fi_vendortest_partition_t uj_output;
322 for (uint32_t i = 0; i < OTP_CTRL_PARAM_VENDOR_TEST_SIZE / 4; i++) {
323 uj_output.vendor_test_comp[i] = otp_read32_result_vendor_test_comp[i];
324 uj_output.vendor_test_fi[i] = otp_read32_result_vendor_test_fi[i];
326 uj_output.otp_status_codes =
status.codes;
327 memcpy(uj_output.otp_error_causes, (uint8_t *)
status.causes,
329 uj_output.alerts[0] = reg_alerts.alerts[0];
330 uj_output.alerts[1] = reg_alerts.alerts[1];
331 uj_output.alerts[2] = reg_alerts.alerts[2];
332 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
333 sizeof(sensor_alerts.alerts));
334 RESP_OK(ujson_serialize_otp_fi_vendortest_partition_t, uj, &uj_output);
340 otp_fi_subcommand_t cmd;
341 TRY(ujson_deserialize_otp_fi_subcommand_t(uj, &cmd));
343 case kOtpFiSubcommandInit:
344 return handle_otp_fi_init(uj);
345 case kOtpFiSubcommandVendorTest:
346 return handle_otp_fi_vendor_test(uj);
347 case kOtpFiSubcommandOwnerSwCfg:
348 return handle_otp_fi_owner_sw_cfg(uj);
349 case kOtpFiSubcommandHwCfg:
350 return handle_otp_fi_hw_cfg(uj);
351 case kOtpFiSubcommandLifeCycle:
352 return handle_otp_fi_life_cycle(uj);
354 LOG_ERROR(
"Unrecognized OTP FI subcommand: %d", cmd);
355 return INVALID_ARGUMENT();