6 #include "sw/device/lib/base/status.h"
8 #include "sw/device/lib/dif/dif_csrng_shared.h"
11 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
13 #include "sw/device/lib/testing/csrng_testutils.h"
14 #include "sw/device/lib/testing/edn_testutils.h"
15 #include "sw/device/lib/testing/entropy_src_testutils.h"
16 #include "sw/device/lib/testing/entropy_testutils.h"
17 #include "sw/device/lib/testing/rv_core_ibex_testutils.h"
18 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
19 #include "sw/device/lib/ujson/ujson.h"
20 #include "sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h"
21 #include "sw/device/tests/penetrationtests/json/rng_fi_commands.h"
27 #define NOP1 "addi x0, x0, 0\n"
28 #define NOP10 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1
29 #define NOP30 NOP10 NOP10 NOP10
32 kEdnKatTimeout = (10 * 1000 * 1000),
33 kCsrngExpectedOutputLen = 16,
34 kEdnBusAckMaxData = 64,
37 kEdnKatOutputLen = 16,
38 kEdnKatWordsPerBlock = 4,
39 kEntropyFifoBufferSize = 32,
40 kCsrngBiasFWFifoBufferSize = 12,
41 kMaxReadCountNotBlocking = 32,
42 kTestParamEntropySrcMaxAttempts = 256,
45 static dif_rv_core_ibex_t rv_core_ibex;
46 static dif_entropy_src_t entropy_src;
47 static dif_csrng_t csrng;
48 static dif_edn_t edn0;
49 static dif_edn_t edn1;
50 static bool disable_health_check;
52 static bool firmware_override_init;
54 static const uint32_t kInputMsg[kCsrngBiasFWFifoBufferSize] = {
55 0xa52a0da9, 0xcae141b2, 0x6d5bab9d, 0x2c3e5cc0, 0x225afc93, 0x5d31a610,
56 0x91b7f960, 0x0d566bb3, 0xef35e170, 0x94ba7d8e, 0x534eb741, 0x6b60b0da,
61 .
len = kEdnKatMaxClen,
62 .data = {0x73bec010, 0x9262474c, 0x16a30f76, 0x531b51de, 0x2ee494e5,
63 0xdfec9db3, 0xcb7a879d, 0x5600419c, 0xca79b0b0, 0xdda33b5c,
64 0xa468649e, 0xdf5d73fa},
68 .
len = kEdnKatMaxClen,
69 .data = {0x73bec010, 0x9262474c, 0x16a30f76, 0x531b51de, 0x2ee494e5,
70 0xdfec9db3, 0xcb7a879d, 0x5600419c, 0xca79b0b0, 0xdda33b5c,
71 0xa468649e, 0xdf5d73fa},
82 .
cmd = csrng_cmd_header_build(kCsrngAppCmdInstantiate,
84 kEdnKatSeedMaterialInstantiate.
len,
86 .seed_material = kEdnKatSeedMaterialInstantiate,
90 .cmd = csrng_cmd_header_build(kCsrngAppCmdReseed,
92 kEdnKatSeedMaterialReseed.
len,
94 .seed_material = kEdnKatSeedMaterialReseed,
98 .cmd = csrng_cmd_header_build(
100 kEdnKatSeedMaterialGenerate.
len,
102 kEdnKatOutputLen / kEdnKatWordsPerBlock),
103 .seed_material = kEdnKatSeedMaterialGenerate,
105 .reseed_interval = 32,
109 static const uint32_t kExpectedOutput[kEdnKatOutputLen] = {
110 0xe48bb8cb, 0x1012c84c, 0x5af8a7f1, 0xd1c07cd9, 0xdf82ab22, 0x771c619b,
111 0xd40fccb1, 0x87189e99, 0x510494b3, 0x64f7ac0c, 0x2581f391, 0x80b1dc2f,
112 0x793e01c5, 0x87b107ae, 0xdb17514c, 0xa43c41b7,
123 static void entropy_data_flush(dif_entropy_src_t *entropy_src) {
124 uint32_t entropy_bits;
125 uint32_t read_count = 0;
129 const uint32_t kMaxReadCount = 128;
133 CHECK(entropy_bits != 0);
135 if (read_count >= kMaxReadCount) {
146 static void entropy_conditioner_stop(
const dif_entropy_src_t *entropy_src) {
147 uint32_t fail_count = 0;
152 CHECK(fail_count++ < kTestParamEntropySrcMaxAttempts);
154 CHECK_DIF_OK(op_result);
163 pentest_clear_sensor_recov_alerts();
170 .route_to_firmware =
true,
172 .health_test_threshold_scope =
false,
173 .health_test_window_size = 0x0200,
174 .alert_threshold = 2,
180 TRY(entropy_src_testutils_wait_for_state(
181 &entropy_src, kDifEntropySrcMainFsmStateContHTRunning));
183 entropy_data_flush(&entropy_src);
185 uint32_t entropy_bits[kMaxReadCountNotBlocking] = {0};
187 pentest_set_trigger_high();
189 for (
size_t it = 0; it < kMaxReadCountNotBlocking; it++) {
195 pentest_set_trigger_low();
198 reg_alerts = pentest_get_triggered_alerts();
203 dif_rv_core_ibex_error_status_t err_ibx;
204 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
207 rng_fi_entropy_src_bias_t uj_output;
209 memcpy(uj_output.rand, entropy_bits,
sizeof(entropy_bits));
210 uj_output.err_status = err_ibx;
211 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
212 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
213 sizeof(sensor_alerts.alerts));
214 RESP_OK(ujson_serialize_rng_fi_entropy_src_bias_t, uj, &uj_output);
223 pentest_clear_sensor_recov_alerts();
225 if (!firmware_override_init) {
227 rng_fi_fw_overwrite_health_t uj_data;
228 TRY(ujson_deserialize_rng_fi_fw_overwrite_health_t(uj, &uj_data));
229 disable_health_check = uj_data.disable_health_check;
231 firmware_override_init =
true;
234 TRY(entropy_testutils_stop_all());
236 if (disable_health_check) {
238 TRY(entropy_src_testutils_disable_health_tests(&entropy_src));
241 TRY(entropy_src_testutils_fw_override_enable(&entropy_src,
242 kEntropyFifoBufferSize,
246 entropy_data_flush(&entropy_src);
248 uint32_t buf[kEntropyFifoBufferSize] = {0};
250 pentest_set_trigger_high();
252 for (
size_t it = 0; it < kEntropyFifoBufferSize; it++) {
253 while (buf[it] == 0) {
255 kEntropyFifoBufferSize));
260 pentest_set_trigger_low();
263 reg_alerts = pentest_get_triggered_alerts();
268 dif_rv_core_ibex_error_status_t err_ibx;
269 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
272 rng_fi_fw_overwrite_t uj_output;
274 memcpy(uj_output.rand, buf,
sizeof(buf));
275 uj_output.err_status = err_ibx;
276 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
277 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
278 sizeof(sensor_alerts.alerts));
279 RESP_OK(ujson_serialize_rng_fi_fw_overwrite_t, uj, &uj_output);
288 pentest_clear_sensor_recov_alerts();
290 TRY(dif_entropy_src_init(
296 TRY(dif_rv_core_ibex_init(
301 edn_testutils_auto_params_build(
true, 0, 0);
303 TRY(entropy_testutils_stop_all());
305 TRY(entropy_testutils_entropy_src_init());
313 uint32_t ibex_rnd_data_got[kEdnBiasMaxData];
315 pentest_set_trigger_high();
317 for (
size_t it = 0; it < kEdnBiasMaxData; it++) {
318 CHECK_STATUS_OK(rv_core_ibex_testutils_get_rnd_data(
319 &rv_core_ibex, kEdnKatTimeout, &ibex_rnd_data_got[it]));
322 pentest_set_trigger_low();
324 rng_fi_edn_t uj_output;
325 memset(uj_output.rand, 0,
sizeof(uj_output.rand));
326 size_t collisions = 0;
327 for (
size_t got = 0; got < kEdnBiasMaxData; got++) {
328 for (
size_t ref = 0; ref < kEdnBiasMaxData; ref++) {
329 if (ibex_rnd_data_got[got] == kExpectedOutput[ref]) {
330 uj_output.rand[collisions] = ibex_rnd_data_got[got];
337 reg_alerts = pentest_get_triggered_alerts();
342 dif_rv_core_ibex_error_status_t err_ibx;
343 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
346 uj_output.collisions = collisions;
347 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
348 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
349 sizeof(sensor_alerts.alerts));
350 uj_output.err_status = err_ibx;
351 RESP_OK(ujson_serialize_rng_fi_edn_t, uj, &uj_output);
359 pentest_clear_sensor_recov_alerts();
363 TRY(entropy_testutils_auto_mode_init());
365 uint32_t ibex_rnd_data[kEdnBusAckMaxData];
370 pentest_set_trigger_high();
372 for (
size_t it = 0; it < kEdnBusAckMaxData; it++) {
373 TRY(rv_core_ibex_testutils_get_rnd_data(&rv_core_ibex, kEdnKatTimeout,
374 &ibex_rnd_data[it]));
376 pentest_set_trigger_low();
379 rng_fi_edn_t uj_output;
380 memset(uj_output.rand, 0,
sizeof(uj_output.rand));
381 size_t collisions = 0;
382 for (
size_t outer = 0; outer < kEdnBusAckMaxData; outer++) {
383 for (
size_t inner = 0; inner < kEdnBusAckMaxData; inner++) {
384 if (outer != inner && ibex_rnd_data[outer] == ibex_rnd_data[inner]) {
385 if (collisions < 16) {
386 uj_output.rand[collisions] = ibex_rnd_data[outer];
394 reg_alerts = pentest_get_triggered_alerts();
399 dif_rv_core_ibex_error_status_t err_ibx;
400 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
403 uj_output.collisions = collisions;
404 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
405 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
406 sizeof(sensor_alerts.alerts));
407 uj_output.err_status = err_ibx;
408 RESP_OK(ujson_serialize_rng_fi_edn_t, uj, &uj_output);
413 penetrationtest_cpuctrl_t uj_data;
414 TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));
416 pentest_select_trigger_type(kPentestTriggerTypeSw);
420 pentest_init(kPentestTriggerSourceAes,
421 kPentestPeripheralIoDiv4 | kPentestPeripheralEntropy |
422 kPentestPeripheralCsrng | kPentestPeripheralEdn);
425 penetrationtest_device_info_t uj_output;
426 TRY(pentest_configure_cpu(
427 uj_data.icache_disable, uj_data.dummy_instr_disable,
428 uj_data.enable_jittery_clock, uj_data.enable_sram_readback,
429 &uj_output.clock_jitter_locked, &uj_output.clock_jitter_en,
430 &uj_output.sram_main_readback_locked, &uj_output.sram_ret_readback_locked,
431 &uj_output.sram_main_readback_en, &uj_output.sram_ret_readback_en));
434 TRY(dif_rv_core_ibex_init(
440 pentest_configure_alert_handler();
443 TRY(dif_entropy_src_init(
451 TRY(pentest_read_device_id(uj_output.device_id));
452 RESP_OK(ujson_serialize_penetrationtest_device_info_t, uj, &uj_output);
454 firmware_override_init =
false;
461 crypto_fi_csrng_mode_t uj_data;
462 TRY(ujson_deserialize_crypto_fi_csrng_mode_t(uj, &uj_data));
466 pentest_clear_sensor_recov_alerts();
468 TRY(csrng_testutils_cmd_ready_wait(&csrng));
472 .
seed_material = {0x73bec010, 0x9262474c, 0x16a30f76, 0x531b51de,
473 0x2ee494e5, 0xdfec9db3, 0xcb7a879d, 0x5600419c,
474 0xca79b0b0, 0xdda33b5c, 0xa468649e, 0xdf5d73fa},
475 .seed_material_len = 12,
482 uint32_t rand_data_got[kCsrngExpectedOutputLen];
483 TRY(csrng_testutils_cmd_ready_wait(&csrng));
485 if (uj_data.all_trigger || uj_data.start_trigger) {
486 pentest_set_trigger_high();
489 if (uj_data.start_trigger) {
490 pentest_set_trigger_low();
493 if (uj_data.valid_trigger) {
494 pentest_set_trigger_high();
500 if (uj_data.valid_trigger) {
501 pentest_set_trigger_low();
504 if (uj_data.read_trigger) {
505 pentest_set_trigger_high();
508 if (uj_data.all_trigger || uj_data.read_trigger) {
509 pentest_set_trigger_low();
513 reg_alerts = pentest_get_triggered_alerts();
518 dif_rv_core_ibex_error_status_t err_ibx;
519 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
522 const uint32_t kExpectedOutput[kCsrngExpectedOutputLen] = {
523 932170270, 3480632584, 387346064, 186012424, 899661374, 2795183089,
524 336687633, 3222931513, 1490543709, 3319795384, 3464147855, 1850271046,
525 1239323641, 2292604615, 3314177342, 1567494162,
527 rng_fi_csrng_output_t uj_output;
529 for (
size_t it = 0; it < kCsrngExpectedOutputLen; it++) {
530 if (rand_data_got[it] != kExpectedOutput[it]) {
536 memcpy(uj_output.rand, rand_data_got,
sizeof(rand_data_got));
537 uj_output.err_status = err_ibx;
538 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
539 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
540 sizeof(sensor_alerts.alerts));
541 RESP_OK(ujson_serialize_rng_fi_csrng_output_t, uj, &uj_output);
546 status_t handle_rng_fi_csrng_bias_fw_override(
ujson_t *uj,
bool static_seed) {
550 pentest_clear_sensor_recov_alerts();
552 uint32_t received_data[kCsrngBiasFWFifoBufferSize];
555 uint32_t seed[kCsrngBiasFWFifoBufferSize];
558 memcpy(seed, kInputMsg,
sizeof(kInputMsg));
560 rng_fi_seed_t uj_data;
561 TRY(ujson_deserialize_rng_fi_seed_t(uj, &uj_data));
562 memcpy(seed, uj_data.seed,
sizeof(uj_data.seed));
565 CHECK_STATUS_OK(entropy_testutils_stop_all());
566 CHECK_STATUS_OK(entropy_src_testutils_fw_override_enable(
567 &entropy_src, kCsrngBiasFWFifoBufferSize,
571 entropy_data_flush(&entropy_src);
577 uint32_t fail_count = 0;
582 &entropy_src, seed + total,
ARRAYSIZE(seed) - total, &count);
585 CHECK(fail_count++ < kTestParamEntropySrcMaxAttempts);
588 CHECK_DIF_OK(op_result);
592 pentest_set_trigger_high();
593 entropy_conditioner_stop(&entropy_src);
595 TRY(csrng_testutils_cmd_ready_wait(&csrng));
597 &kEmptySeedMaterial));
599 CHECK_STATUS_OK(csrng_testutils_cmd_generate_run(&csrng, received_data,
603 pentest_set_trigger_low();
606 reg_alerts = pentest_get_triggered_alerts();
611 dif_rv_core_ibex_error_status_t err_ibx;
612 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
614 rng_fi_csrng_ov_output_t uj_output;
618 memcpy(uj_output.rand, received_data,
sizeof(received_data));
619 uj_output.err_status = err_ibx;
620 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
621 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
622 sizeof(sensor_alerts.alerts));
623 RESP_OK(ujson_serialize_rng_fi_csrng_ov_output_t, uj, &uj_output);
629 penetrationtest_cpuctrl_t uj_data;
630 TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));
632 pentest_select_trigger_type(kPentestTriggerTypeSw);
636 pentest_init(kPentestTriggerSourceAes,
637 kPentestPeripheralIoDiv4 | kPentestPeripheralCsrng);
640 penetrationtest_device_info_t uj_output;
641 TRY(pentest_configure_cpu(
642 uj_data.icache_disable, uj_data.dummy_instr_disable,
643 uj_data.enable_jittery_clock, uj_data.enable_sram_readback,
644 &uj_output.clock_jitter_locked, &uj_output.clock_jitter_en,
645 &uj_output.sram_main_readback_locked, &uj_output.sram_ret_readback_locked,
646 &uj_output.sram_main_readback_en, &uj_output.sram_ret_readback_en));
649 TRY(dif_rv_core_ibex_init(
655 pentest_configure_alert_handler();
659 CHECK_DIF_OK(dif_csrng_init(base_addr, &csrng));
663 TRY(pentest_read_device_id(uj_output.device_id));
664 RESP_OK(ujson_serialize_penetrationtest_device_info_t, uj, &uj_output);
670 rng_fi_subcommand_t cmd;
671 TRY(ujson_deserialize_rng_fi_subcommand_t(uj, &cmd));
673 case kRngFiSubcommandCsrngInit:
674 return handle_rng_fi_csrng_init(uj);
675 case kRngFiSubcommandCsrngBias:
676 return handle_rng_fi_csrng_bias(uj);
677 case kRngFiSubcommandCsrngBiasFWOverride:
678 return handle_rng_fi_csrng_bias_fw_override(uj,
false);
679 case kRngFiSubcommandCsrngBiasFWOverrideStatic:
680 return handle_rng_fi_csrng_bias_fw_override(uj,
true);
681 case kRngFiSubcommandEdnInit:
682 return handle_rng_fi_edn_init(uj);
683 case kRngFiSubcommandEdnRespAck:
684 return handle_rng_fi_edn_resp_ack(uj);
685 case kRngFiSubcommandEdnBias:
686 return handle_rng_fi_edn_bias(uj);
687 case kRngFiSubcommandFWOverride:
688 return handle_rng_fi_firmware_override(uj);
689 case kRngFiSubcommandEntropySrcBias:
690 return handle_rng_fi_entropy_src_bias(uj);
692 LOG_ERROR(
"Unrecognized RNG FI subcommand: %d", cmd);
693 return INVALID_ARGUMENT();