5 #include "sw/device/tests/penetrationtests/firmware/fi/crypto_fi.h"
7 #include "hw/ip/aes/model/aes_modes.h"
10 #include "sw/device/lib/base/status.h"
14 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
16 #include "sw/device/lib/testing/aes_testutils.h"
17 #include "sw/device/lib/testing/hmac_testutils.h"
18 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
19 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
20 #include "sw/device/lib/ujson/ujson.h"
21 #include "sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h"
22 #include "sw/device/tests/penetrationtests/json/crypto_fi_commands.h"
26 #include "kmac_regs.h"
28 #define SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
29 abs_mmio_write32_shadowed(shadow_reg_addr, tmp); \
30 tmp = abs_mmio_read32(shadow_reg_addr);
32 #define SHADOW_REG_ACCESS_10(shadow_reg_addr, tmp) \
33 SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
34 SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
35 SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
36 SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
37 SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
38 SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
39 SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
40 SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
41 SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
42 SHADOW_REG_ACCESS(shadow_reg_addr, tmp)
48 kAesWaitTimeout = 1000000,
52 static dif_kmac_t kmac;
53 static dif_hmac_t hmac;
55 static dif_rv_core_ibex_t rv_core_ibex;
75 const char *customization_string;
76 size_t customization_string_len;
78 const uint32_t digest[16];
80 bool digest_len_is_fixed;
91 .share0 = {0x43424140, 0x47464544, 0x4b4a4948, 0x4f4e4f4c,
92 0x53525150, 0x57565554, 0x5b5a5958, 0x5f5e5d5c},
97 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
98 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
99 "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
100 "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
101 "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
102 "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
103 "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
104 "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
105 "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
106 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
107 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
108 "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
109 "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7",
111 .customization_string =
"My Tagged Application",
112 .customization_string_len = 21,
113 .digest = {0x1c73bed5, 0x73d74e95, 0x59bb4628, 0xe3a8e3db, 0x7ae7830f,
114 0x5944ff4b, 0xb4c2f1f2, 0xceb8ebec, 0xc601ba67, 0x57b88a2e,
115 0x9b492d8d, 0x6727bbd1, 0x90117868, 0x6a300a02, 0x1d28de97,
118 .digest_len_is_fixed =
false,
121 static const uint8_t kKeyShare1[] = {
122 0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f, 0x8f, 0x9f, 0xaf,
123 0xbf, 0xcf, 0xdf, 0xef, 0xff, 0x0a, 0x1a, 0x2a, 0x3a, 0x4a, 0x5a,
124 0x6a, 0x7a, 0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa,
134 .reseed_on_key_change =
false,
135 .force_masks =
false,
136 .ctrl_aux_lock =
false,
142 static inline uint32_t aes_spin_until(uint32_t bit) {
158 crypto_fi_aes_mode_t uj_data;
159 TRY(ujson_deserialize_crypto_fi_aes_mode_t(uj, &uj_data));
163 pentest_clear_sensor_recov_alerts();
168 if (uj_data.key_trigger) {
169 pentest_set_trigger_high();
171 TRY(
dif_aes_start(&aes, &transaction, &aes_key_shares, NULL));
176 if (uj_data.key_trigger) {
177 pentest_set_trigger_low();
185 if (uj_data.plaintext_trigger) {
186 pentest_set_trigger_high();
189 if (uj_data.plaintext_trigger) {
190 pentest_set_trigger_low();
195 if (uj_data.encrypt_trigger) {
196 pentest_set_trigger_high();
205 if (uj_data.encrypt_trigger) {
206 pentest_set_trigger_low();
212 if (uj_data.ciphertext_trigger) {
213 pentest_set_trigger_high();
216 if (uj_data.ciphertext_trigger) {
217 pentest_set_trigger_low();
221 reg_alerts = pentest_get_triggered_alerts();
226 dif_rv_core_ibex_error_status_t codes;
227 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
230 crypto_fi_aes_ciphertext_t uj_output;
231 uj_output.err_status = codes;
232 memcpy(uj_output.ciphertext, ciphertext.data, 16);
233 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
234 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
235 sizeof(sensor_alerts.alerts));
236 RESP_OK(ujson_serialize_crypto_fi_aes_ciphertext_t, uj, &uj_output);
241 penetrationtest_cpuctrl_t uj_data;
242 TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));
244 pentest_select_trigger_type(kPentestTriggerTypeSw);
245 pentest_init(kPentestTriggerSourceAes,
246 kPentestPeripheralIoDiv4 | kPentestPeripheralAes |
247 kPentestPeripheralKmac | kPentestPeripheralEdn |
248 kPentestPeripheralCsrng | kPentestPeripheralEntropy |
249 kPentestPeripheralHmac);
252 pentest_configure_alert_handler();
255 penetrationtest_device_info_t uj_output;
256 TRY(pentest_configure_cpu(
257 uj_data.icache_disable, uj_data.dummy_instr_disable,
258 uj_data.enable_jittery_clock, uj_data.enable_sram_readback,
259 &uj_output.clock_jitter_locked, &uj_output.clock_jitter_en,
260 &uj_output.sram_main_readback_locked, &uj_output.sram_ret_readback_locked,
261 &uj_output.sram_main_readback_en, &uj_output.sram_ret_readback_en));
268 uint8_t key_share0[
sizeof(kAesModesKey256)];
269 for (
int i = 0; i <
sizeof(kAesModesKey256); ++i) {
270 key_share0[i] = kAesModesKey256[i] ^ kKeyShare1[i];
276 memcpy(aes_plaintext.data, kAesModesPlainText,
sizeof(aes_plaintext.data));
284 .entropy_seed = {0xaa25b4bf, 0x48ce8fff, 0x5a78282a, 0x48465647,
296 TRY(dif_hmac_init(base_addr, &hmac));
299 TRY(dif_rv_core_ibex_init(
304 TRY(pentest_read_device_id(uj_output.device_id));
305 RESP_OK(ujson_serialize_penetrationtest_device_info_t, uj, &uj_output);
312 crypto_fi_kmac_mode_t uj_data;
313 TRY(ujson_deserialize_crypto_fi_kmac_mode_t(uj, &uj_data));
317 pentest_clear_sensor_recov_alerts();
322 if (uj_data.key_trigger) {
323 pentest_set_trigger_high();
327 kKmacTestVector.mode, 0, &kKmacTestVector.key,
329 if (uj_data.key_trigger) {
330 pentest_set_trigger_low();
334 if (uj_data.absorb_trigger) {
335 pentest_set_trigger_high();
337 TRY(
dif_kmac_absorb(&kmac, &kmac_operation_state, kKmacTestVector.message,
338 kKmacTestVector.message_len, NULL));
339 if (uj_data.absorb_trigger) {
340 pentest_set_trigger_low();
344 if (uj_data.static_trigger) {
345 pentest_set_trigger_high();
350 if (uj_data.static_trigger) {
351 pentest_set_trigger_low();
355 uint32_t digest[kKmacTestVector.digest_len];
356 if (uj_data.squeeze_trigger) {
357 pentest_set_trigger_high();
360 kKmacTestVector.digest_len, NULL,
362 if (uj_data.squeeze_trigger) {
363 pentest_set_trigger_low();
369 uint32_t digest_2nd[kKmacTestVector.digest_len];
371 kKmacTestVector.digest_len, NULL,
375 reg_alerts = pentest_get_triggered_alerts();
382 dif_rv_core_ibex_error_status_t codes;
383 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
386 crypto_fi_kmac_digest_t uj_output;
387 uj_output.err_status = codes;
388 memcpy(uj_output.digest, (uint8_t *)digest, 8);
389 memcpy(uj_output.digest_2nd, (uint8_t *)digest_2nd, 8);
390 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
391 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
392 sizeof(sensor_alerts.alerts));
393 RESP_OK(ujson_serialize_crypto_fi_kmac_digest_t, uj, &uj_output);
401 pentest_clear_sensor_recov_alerts();
406 kKmacTestVector.mode, 0, &kKmacTestVector.key,
409 TRY(
dif_kmac_absorb(&kmac, &kmac_operation_state, kKmacTestVector.message,
410 kKmacTestVector.message_len, NULL));
413 uint32_t digest[kKmacTestVector.digest_len];
415 kKmacTestVector.digest_len, NULL,
419 pentest_set_trigger_high();
423 pentest_set_trigger_low();
426 reg_alerts = pentest_get_triggered_alerts();
431 dif_rv_core_ibex_error_status_t codes;
432 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
435 crypto_fi_kmac_state_t uj_output;
438 ptrdiff_t offset = KMAC_STATE_REG_OFFSET;
439 for (
size_t i = 0; i < 200; i++) {
440 uj_output.share0[i] = mmio_region_read8(base, offset);
441 uj_output.share1[i] =
443 offset +=
sizeof(uint8_t);
446 uj_output.err_status = codes;
447 memcpy(uj_output.digest, (uint8_t *)digest, 8);
448 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
449 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
450 sizeof(sensor_alerts.alerts));
452 RESP_OK(ujson_serialize_crypto_fi_kmac_state_t, uj, &uj_output);
460 crypto_fi_hmac_message_t uj_msg;
461 TRY(ujson_deserialize_crypto_fi_hmac_message_t(uj, &uj_msg));
463 crypto_fi_hmac_mode_t uj_data;
464 TRY(ujson_deserialize_crypto_fi_hmac_mode_t(uj, &uj_data));
468 if (uj_data.start_trigger) {
469 pentest_set_trigger_high();
472 if (uj_data.start_trigger) {
473 pentest_set_trigger_low();
476 if (uj_data.msg_trigger) {
477 pentest_set_trigger_high();
479 TRY(hmac_testutils_push_message(&hmac, (
char *)uj_msg.message,
480 sizeof(uj_msg.message)));
481 if (uj_data.msg_trigger) {
482 pentest_set_trigger_low();
485 if (uj_data.process_trigger) {
486 pentest_set_trigger_high();
489 if (uj_data.process_trigger) {
490 pentest_set_trigger_low();
494 if (uj_data.finish_trigger) {
495 pentest_set_trigger_high();
497 TRY(hmac_testutils_finish_polled(&hmac, &digest));
498 if (uj_data.finish_trigger) {
499 pentest_set_trigger_low();
503 reg_alerts = pentest_get_triggered_alerts();
506 dif_rv_core_ibex_error_status_t codes;
507 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
510 crypto_fi_hmac_tag_t uj_output;
511 uj_output.err_status = codes;
512 memcpy(uj_output.tag, digest.digest,
sizeof(uj_output.tag));
513 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
514 RESP_OK(ujson_serialize_crypto_fi_hmac_tag_t, uj, &uj_output);
522 pentest_clear_sensor_recov_alerts();
524 crypto_fi_test_result_mult_t uj_output;
527 uint32_t ctrl_reg_kmac = KMAC_CFG_SHADOWED_REG_RESVAL;
529 KMAC_CFG_SHADOWED_MSG_ENDIANNESS_BIT, 1);
531 ctrl_reg_kmac, KMAC_CFG_SHADOWED_STATE_ENDIANNESS_BIT, 1);
535 ctrl_reg_kmac, KMAC_CFG_SHADOWED_ENTROPY_FAST_PROCESS_BIT, 0);
539 KMAC_CFG_SHADOWED_ENTROPY_READY_BIT, 0);
541 ctrl_reg_kmac, KMAC_CFG_SHADOWED_EN_UNSUPPORTED_MODESTRENGTH_BIT, 1);
543 uint32_t ctrl_reg_kmac_addr =
546 pentest_set_trigger_high();
548 SHADOW_REG_ACCESS_10(ctrl_reg_kmac_addr, ctrl_reg_kmac)
549 SHADOW_REG_ACCESS_10(ctrl_reg_kmac_addr, ctrl_reg_kmac)
550 SHADOW_REG_ACCESS_10(ctrl_reg_kmac_addr, ctrl_reg_kmac)
552 pentest_set_trigger_low();
555 reg_alerts = pentest_get_triggered_alerts();
560 dif_rv_core_ibex_error_status_t codes;
561 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
565 KMAC_CFG_SHADOWED_REG_OFFSET);
566 uj_output.result[0] = ctrl_reg_kmac_read;
568 uj_output.result[1] = 0;
569 uj_output.result[2] = 0;
571 uj_output.err_status = codes;
572 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
573 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
574 sizeof(sensor_alerts.alerts));
575 RESP_OK(ujson_serialize_crypto_fi_test_result_mult_t, uj, &uj_output);
584 pentest_clear_sensor_recov_alerts();
586 crypto_fi_test_result_mult_t uj_output;
589 uint32_t ctrl_reg_aes_init = AES_CTRL_SHADOWED_REG_RESVAL;
592 AES_CTRL_SHADOWED_KEY_LEN_VALUE_AES_128);
595 AES_CTRL_SHADOWED_MODE_VALUE_AES_ECB);
597 ctrl_reg_aes_init, AES_CTRL_SHADOWED_PRNG_RESEED_RATE_FIELD,
598 AES_CTRL_SHADOWED_PRNG_RESEED_RATE_VALUE_PER_64);
600 ctrl_reg_aes_init, AES_CTRL_SHADOWED_SIDELOAD_BIT,
true);
602 ctrl_reg_aes_init, AES_CTRL_SHADOWED_OPERATION_FIELD,
603 AES_CTRL_SHADOWED_OPERATION_VALUE_AES_DEC);
605 ctrl_reg_aes_init, AES_CTRL_SHADOWED_MANUAL_OPERATION_BIT,
true);
606 abs_mmio_write32_shadowed(
609 aes_spin_until(AES_STATUS_IDLE_BIT);
611 uint32_t ctrl_reg_kmac_init = KMAC_CFG_SHADOWED_REG_RESVAL;
613 ctrl_reg_kmac_init, KMAC_CFG_SHADOWED_MSG_ENDIANNESS_BIT, 0);
615 ctrl_reg_kmac_init, KMAC_CFG_SHADOWED_STATE_ENDIANNESS_BIT, 0);
617 KMAC_CFG_SHADOWED_SIDELOAD_BIT, 0);
619 ctrl_reg_kmac_init, KMAC_CFG_SHADOWED_ENTROPY_FAST_PROCESS_BIT, 1);
621 KMAC_CFG_SHADOWED_MSG_MASK_BIT, 0);
623 ctrl_reg_kmac_init, KMAC_CFG_SHADOWED_ENTROPY_READY_BIT, 1);
625 ctrl_reg_kmac_init, KMAC_CFG_SHADOWED_EN_UNSUPPORTED_MODESTRENGTH_BIT, 0);
626 abs_mmio_write32_shadowed(
630 pentest_set_trigger_high();
633 AES_CTRL_SHADOWED_REG_OFFSET);
635 KMAC_CFG_SHADOWED_REG_OFFSET);
637 pentest_set_trigger_low();
640 reg_alerts = pentest_get_triggered_alerts();
645 dif_rv_core_ibex_error_status_t codes;
646 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
649 uj_output.result[0] = 0;
650 if (ctrl_reg_aes_read != ctrl_reg_aes_init) {
651 uj_output.result[0] = ctrl_reg_aes_read;
654 uj_output.result[1] = 0;
655 if (ctrl_reg_kmac_read != ctrl_reg_kmac_init) {
656 uj_output.result[1] = ctrl_reg_kmac_read;
659 uj_output.result[2] = 0;
661 uj_output.err_status = codes;
662 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
663 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
664 sizeof(sensor_alerts.alerts));
665 RESP_OK(ujson_serialize_crypto_fi_test_result_mult_t, uj, &uj_output);
671 crypto_fi_subcommand_t cmd;
672 TRY(ujson_deserialize_crypto_fi_subcommand_t(uj, &cmd));
674 case kCryptoFiSubcommandAes:
675 return handle_crypto_fi_aes(uj);
676 case kCryptoFiSubcommandInit:
677 return handle_crypto_fi_init(uj);
678 case kCryptoFiSubcommandKmac:
679 return handle_crypto_fi_kmac(uj);
680 case kCryptoFiSubcommandKmacState:
681 return handle_crypto_fi_kmac_state(uj);
682 case kCryptoFiSubcommandSha256:
683 return handle_crypto_fi_sha256(uj);
684 case kCryptoFiSubcommandShadowRegAccess:
685 return handle_crypto_fi_shadow_reg_access(uj);
686 case kCryptoFiSubcommandShadowRegRead:
687 return handle_crypto_fi_shadow_reg_read(uj);
689 LOG_ERROR(
"Unrecognized Crypto FI subcommand: %d", cmd);
690 return INVALID_ARGUMENT();