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 kEdnKatTimeout = (10 * 1000 * 1000),
28 kCsrngExpectedOutputLen = 16,
29 kEdnBusAckMaxData = 64,
32 kEdnKatOutputLen = 16,
33 kEdnKatWordsPerBlock = 4,
34 kEntropyFifoBufferSize = 32,
35 kCsrngBiasFWFifoBufferSize = 12,
36 kMaxReadCountNotBlocking = 32,
37 kTestParamEntropySrcMaxAttempts = 256,
40 static dif_rv_core_ibex_t rv_core_ibex;
41 static dif_entropy_src_t entropy_src;
42 static dif_csrng_t csrng;
43 static dif_edn_t edn0;
44 static dif_edn_t edn1;
45 static bool disable_health_check;
47 static bool firmware_override_init;
49 static const uint32_t kInputMsg[kCsrngBiasFWFifoBufferSize] = {
50 0xa52a0da9, 0xcae141b2, 0x6d5bab9d, 0x2c3e5cc0, 0x225afc93, 0x5d31a610,
51 0x91b7f960, 0x0d566bb3, 0xef35e170, 0x94ba7d8e, 0x534eb741, 0x6b60b0da,
56 .
len = kEdnKatMaxClen,
57 .data = {0x73bec010, 0x9262474c, 0x16a30f76, 0x531b51de, 0x2ee494e5,
58 0xdfec9db3, 0xcb7a879d, 0x5600419c, 0xca79b0b0, 0xdda33b5c,
59 0xa468649e, 0xdf5d73fa},
63 .
len = kEdnKatMaxClen,
64 .data = {0x73bec010, 0x9262474c, 0x16a30f76, 0x531b51de, 0x2ee494e5,
65 0xdfec9db3, 0xcb7a879d, 0x5600419c, 0xca79b0b0, 0xdda33b5c,
66 0xa468649e, 0xdf5d73fa},
77 .
cmd = csrng_cmd_header_build(kCsrngAppCmdInstantiate,
79 kEdnKatSeedMaterialInstantiate.
len,
81 .seed_material = kEdnKatSeedMaterialInstantiate,
85 .cmd = csrng_cmd_header_build(kCsrngAppCmdReseed,
87 kEdnKatSeedMaterialReseed.
len,
89 .seed_material = kEdnKatSeedMaterialReseed,
93 .cmd = csrng_cmd_header_build(
95 kEdnKatSeedMaterialGenerate.
len,
97 kEdnKatOutputLen / kEdnKatWordsPerBlock),
98 .seed_material = kEdnKatSeedMaterialGenerate,
100 .reseed_interval = 32,
104 static const uint32_t kExpectedOutput[kEdnKatOutputLen] = {
105 0xe48bb8cb, 0x1012c84c, 0x5af8a7f1, 0xd1c07cd9, 0xdf82ab22, 0x771c619b,
106 0xd40fccb1, 0x87189e99, 0x510494b3, 0x64f7ac0c, 0x2581f391, 0x80b1dc2f,
107 0x793e01c5, 0x87b107ae, 0xdb17514c, 0xa43c41b7,
118 static void entropy_data_flush(dif_entropy_src_t *entropy_src) {
119 uint32_t entropy_bits;
120 uint32_t read_count = 0;
124 const uint32_t kMaxReadCount = 128;
128 CHECK(entropy_bits != 0);
130 if (read_count >= kMaxReadCount) {
141 static void entropy_conditioner_stop(
const dif_entropy_src_t *entropy_src) {
142 uint32_t fail_count = 0;
147 CHECK(fail_count++ < kTestParamEntropySrcMaxAttempts);
149 CHECK_DIF_OK(op_result);
158 pentest_clear_sensor_recov_alerts();
165 .route_to_firmware =
true,
167 .health_test_threshold_scope =
false,
168 .health_test_window_size = 0x0200,
169 .alert_threshold = 2,
175 TRY(entropy_src_testutils_wait_for_state(
176 &entropy_src, kDifEntropySrcMainFsmStateContHTRunning));
178 entropy_data_flush(&entropy_src);
180 uint32_t entropy_bits[kMaxReadCountNotBlocking] = {0};
182 pentest_set_trigger_high();
184 for (
size_t it = 0; it < kMaxReadCountNotBlocking; it++) {
190 pentest_set_trigger_low();
193 reg_alerts = pentest_get_triggered_alerts();
198 dif_rv_core_ibex_error_status_t err_ibx;
199 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
202 rng_fi_entropy_src_bias_t uj_output;
204 memcpy(uj_output.rand, entropy_bits,
sizeof(entropy_bits));
205 uj_output.err_status = err_ibx;
206 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
207 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
208 sizeof(sensor_alerts.alerts));
209 RESP_OK(ujson_serialize_rng_fi_entropy_src_bias_t, uj, &uj_output);
218 pentest_clear_sensor_recov_alerts();
220 if (!firmware_override_init) {
222 rng_fi_fw_overwrite_health_t uj_data;
223 TRY(ujson_deserialize_rng_fi_fw_overwrite_health_t(uj, &uj_data));
224 disable_health_check = uj_data.disable_health_check;
226 firmware_override_init =
true;
229 TRY(entropy_testutils_stop_all());
231 if (disable_health_check) {
233 TRY(entropy_src_testutils_disable_health_tests(&entropy_src));
236 TRY(entropy_src_testutils_fw_override_enable(&entropy_src,
237 kEntropyFifoBufferSize,
241 entropy_data_flush(&entropy_src);
243 uint32_t buf[kEntropyFifoBufferSize] = {0};
245 pentest_set_trigger_high();
247 for (
size_t it = 0; it < kEntropyFifoBufferSize; it++) {
248 while (buf[it] == 0) {
250 kEntropyFifoBufferSize));
255 pentest_set_trigger_low();
258 reg_alerts = pentest_get_triggered_alerts();
263 dif_rv_core_ibex_error_status_t err_ibx;
264 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
267 rng_fi_fw_overwrite_t uj_output;
269 memcpy(uj_output.rand, buf,
sizeof(buf));
270 uj_output.err_status = err_ibx;
271 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
272 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
273 sizeof(sensor_alerts.alerts));
274 RESP_OK(ujson_serialize_rng_fi_fw_overwrite_t, uj, &uj_output);
283 pentest_clear_sensor_recov_alerts();
285 TRY(dif_entropy_src_init(
291 TRY(dif_rv_core_ibex_init(
296 edn_testutils_auto_params_build(
true, 0, 0);
298 TRY(entropy_testutils_stop_all());
300 TRY(entropy_testutils_entropy_src_init());
308 uint32_t ibex_rnd_data_got[kEdnBiasMaxData];
310 pentest_set_trigger_high();
312 for (
size_t it = 0; it < kEdnBiasMaxData; it++) {
313 CHECK_STATUS_OK(rv_core_ibex_testutils_get_rnd_data(
314 &rv_core_ibex, kEdnKatTimeout, &ibex_rnd_data_got[it]));
317 pentest_set_trigger_low();
319 rng_fi_edn_t uj_output;
320 memset(uj_output.rand, 0,
sizeof(uj_output.rand));
321 size_t collisions = 0;
322 for (
size_t got = 0; got < kEdnBiasMaxData; got++) {
323 for (
size_t ref = 0; ref < kEdnBiasMaxData; ref++) {
324 if (ibex_rnd_data_got[got] == kExpectedOutput[ref]) {
325 uj_output.rand[collisions] = ibex_rnd_data_got[got];
332 reg_alerts = pentest_get_triggered_alerts();
337 dif_rv_core_ibex_error_status_t err_ibx;
338 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
341 uj_output.collisions = collisions;
342 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
343 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
344 sizeof(sensor_alerts.alerts));
345 uj_output.err_status = err_ibx;
346 RESP_OK(ujson_serialize_rng_fi_edn_t, uj, &uj_output);
354 pentest_clear_sensor_recov_alerts();
358 TRY(entropy_testutils_auto_mode_init());
360 uint32_t ibex_rnd_data[kEdnBusAckMaxData];
365 pentest_set_trigger_high();
367 for (
size_t it = 0; it < kEdnBusAckMaxData; it++) {
368 TRY(rv_core_ibex_testutils_get_rnd_data(&rv_core_ibex, kEdnKatTimeout,
369 &ibex_rnd_data[it]));
371 pentest_set_trigger_low();
374 rng_fi_edn_t uj_output;
375 memset(uj_output.rand, 0,
sizeof(uj_output.rand));
376 size_t collisions = 0;
377 for (
size_t outer = 0; outer < kEdnBusAckMaxData; outer++) {
378 for (
size_t inner = 0; inner < kEdnBusAckMaxData; inner++) {
379 if (outer != inner && ibex_rnd_data[outer] == ibex_rnd_data[inner]) {
380 if (collisions < 16) {
381 uj_output.rand[collisions] = ibex_rnd_data[outer];
389 reg_alerts = pentest_get_triggered_alerts();
394 dif_rv_core_ibex_error_status_t err_ibx;
395 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
398 uj_output.collisions = collisions;
399 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
400 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
401 sizeof(sensor_alerts.alerts));
402 uj_output.err_status = err_ibx;
403 RESP_OK(ujson_serialize_rng_fi_edn_t, uj, &uj_output);
408 penetrationtest_cpuctrl_t uj_data;
409 TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));
411 pentest_select_trigger_type(kPentestTriggerTypeSw);
415 pentest_init(kPentestTriggerSourceAes,
416 kPentestPeripheralIoDiv4 | kPentestPeripheralEntropy |
417 kPentestPeripheralCsrng | kPentestPeripheralEdn);
420 penetrationtest_device_info_t uj_output;
421 TRY(pentest_configure_cpu(
422 uj_data.icache_disable, uj_data.dummy_instr_disable,
423 uj_data.enable_jittery_clock, uj_data.enable_sram_readback,
424 &uj_output.clock_jitter_locked, &uj_output.clock_jitter_en,
425 &uj_output.sram_main_readback_locked, &uj_output.sram_ret_readback_locked,
426 &uj_output.sram_main_readback_en, &uj_output.sram_ret_readback_en));
429 TRY(dif_rv_core_ibex_init(
435 pentest_configure_alert_handler();
438 TRY(dif_entropy_src_init(
446 TRY(pentest_read_device_id(uj_output.device_id));
447 RESP_OK(ujson_serialize_penetrationtest_device_info_t, uj, &uj_output);
449 firmware_override_init =
false;
456 crypto_fi_csrng_mode_t uj_data;
457 TRY(ujson_deserialize_crypto_fi_csrng_mode_t(uj, &uj_data));
461 pentest_clear_sensor_recov_alerts();
463 TRY(csrng_testutils_cmd_ready_wait(&csrng));
467 .
seed_material = {0x73bec010, 0x9262474c, 0x16a30f76, 0x531b51de,
468 0x2ee494e5, 0xdfec9db3, 0xcb7a879d, 0x5600419c,
469 0xca79b0b0, 0xdda33b5c, 0xa468649e, 0xdf5d73fa},
470 .seed_material_len = 12,
477 uint32_t rand_data_got[kCsrngExpectedOutputLen];
478 TRY(csrng_testutils_cmd_ready_wait(&csrng));
480 if (uj_data.all_trigger || uj_data.start_trigger) {
481 pentest_set_trigger_high();
484 if (uj_data.start_trigger) {
485 pentest_set_trigger_low();
488 if (uj_data.valid_trigger) {
489 pentest_set_trigger_high();
495 if (uj_data.valid_trigger) {
496 pentest_set_trigger_low();
499 if (uj_data.read_trigger) {
500 pentest_set_trigger_high();
503 if (uj_data.all_trigger || uj_data.read_trigger) {
504 pentest_set_trigger_low();
508 reg_alerts = pentest_get_triggered_alerts();
513 dif_rv_core_ibex_error_status_t err_ibx;
514 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
517 const uint32_t kExpectedOutput[kCsrngExpectedOutputLen] = {
518 932170270, 3480632584, 387346064, 186012424, 899661374, 2795183089,
519 336687633, 3222931513, 1490543709, 3319795384, 3464147855, 1850271046,
520 1239323641, 2292604615, 3314177342, 1567494162,
522 rng_fi_csrng_output_t uj_output;
524 for (
size_t it = 0; it < kCsrngExpectedOutputLen; it++) {
525 if (rand_data_got[it] != kExpectedOutput[it]) {
531 memcpy(uj_output.rand, rand_data_got,
sizeof(rand_data_got));
532 uj_output.err_status = err_ibx;
533 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
534 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
535 sizeof(sensor_alerts.alerts));
536 RESP_OK(ujson_serialize_rng_fi_csrng_output_t, uj, &uj_output);
541 status_t handle_rng_fi_csrng_bias_fw_override(
ujson_t *uj,
bool static_seed) {
545 pentest_clear_sensor_recov_alerts();
547 uint32_t received_data[kCsrngBiasFWFifoBufferSize];
550 uint32_t seed[kCsrngBiasFWFifoBufferSize];
553 memcpy(seed, kInputMsg,
sizeof(kInputMsg));
555 rng_fi_seed_t uj_data;
556 TRY(ujson_deserialize_rng_fi_seed_t(uj, &uj_data));
557 memcpy(seed, uj_data.seed,
sizeof(uj_data.seed));
560 CHECK_STATUS_OK(entropy_testutils_stop_all());
561 CHECK_STATUS_OK(entropy_src_testutils_fw_override_enable(
562 &entropy_src, kCsrngBiasFWFifoBufferSize,
566 entropy_data_flush(&entropy_src);
572 uint32_t fail_count = 0;
577 &entropy_src, seed + total,
ARRAYSIZE(seed) - total, &count);
580 CHECK(fail_count++ < kTestParamEntropySrcMaxAttempts);
583 CHECK_DIF_OK(op_result);
587 pentest_set_trigger_high();
588 entropy_conditioner_stop(&entropy_src);
590 TRY(csrng_testutils_cmd_ready_wait(&csrng));
592 &kEmptySeedMaterial));
594 CHECK_STATUS_OK(csrng_testutils_cmd_generate_run(&csrng, received_data,
598 pentest_set_trigger_low();
601 reg_alerts = pentest_get_triggered_alerts();
606 dif_rv_core_ibex_error_status_t err_ibx;
607 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &err_ibx));
609 rng_fi_csrng_ov_output_t uj_output;
613 memcpy(uj_output.rand, received_data,
sizeof(received_data));
614 uj_output.err_status = err_ibx;
615 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
616 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
617 sizeof(sensor_alerts.alerts));
618 RESP_OK(ujson_serialize_rng_fi_csrng_ov_output_t, uj, &uj_output);
624 penetrationtest_cpuctrl_t uj_data;
625 TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));
627 pentest_select_trigger_type(kPentestTriggerTypeSw);
631 pentest_init(kPentestTriggerSourceAes,
632 kPentestPeripheralIoDiv4 | kPentestPeripheralCsrng);
635 penetrationtest_device_info_t uj_output;
636 TRY(pentest_configure_cpu(
637 uj_data.icache_disable, uj_data.dummy_instr_disable,
638 uj_data.enable_jittery_clock, uj_data.enable_sram_readback,
639 &uj_output.clock_jitter_locked, &uj_output.clock_jitter_en,
640 &uj_output.sram_main_readback_locked, &uj_output.sram_ret_readback_locked,
641 &uj_output.sram_main_readback_en, &uj_output.sram_ret_readback_en));
644 TRY(dif_rv_core_ibex_init(
650 pentest_configure_alert_handler();
654 CHECK_DIF_OK(dif_csrng_init(base_addr, &csrng));
658 TRY(pentest_read_device_id(uj_output.device_id));
659 RESP_OK(ujson_serialize_penetrationtest_device_info_t, uj, &uj_output);
665 rng_fi_subcommand_t cmd;
666 TRY(ujson_deserialize_rng_fi_subcommand_t(uj, &cmd));
668 case kRngFiSubcommandCsrngInit:
669 return handle_rng_fi_csrng_init(uj);
670 case kRngFiSubcommandCsrngBias:
671 return handle_rng_fi_csrng_bias(uj);
672 case kRngFiSubcommandCsrngBiasFWOverride:
673 return handle_rng_fi_csrng_bias_fw_override(uj,
false);
674 case kRngFiSubcommandCsrngBiasFWOverrideStatic:
675 return handle_rng_fi_csrng_bias_fw_override(uj,
true);
676 case kRngFiSubcommandEdnInit:
677 return handle_rng_fi_edn_init(uj);
678 case kRngFiSubcommandEdnRespAck:
679 return handle_rng_fi_edn_resp_ack(uj);
680 case kRngFiSubcommandEdnBias:
681 return handle_rng_fi_edn_bias(uj);
682 case kRngFiSubcommandFWOverride:
683 return handle_rng_fi_firmware_override(uj);
684 case kRngFiSubcommandEntropySrcBias:
685 return handle_rng_fi_entropy_src_bias(uj);
687 LOG_ERROR(
"Unrecognized RNG FI subcommand: %d", cmd);
688 return INVALID_ARGUMENT();