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"
13 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
15 #include "sw/device/lib/testing/aes_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/crypto_fi_commands.h"
24 #include "kmac_regs.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
31 #define SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
32 abs_mmio_write32_shadowed(shadow_reg_addr, tmp); \
33 tmp = abs_mmio_read32(shadow_reg_addr);
35 #define SHADOW_REG_ACCESS_10(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) \
43 SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
44 SHADOW_REG_ACCESS(shadow_reg_addr, tmp) \
45 SHADOW_REG_ACCESS(shadow_reg_addr, tmp)
51 kAesWaitTimeout = 1000000,
55 static dif_kmac_t kmac;
57 static dif_rv_core_ibex_t rv_core_ibex;
72 const char *customization_string;
73 size_t customization_string_len;
75 const uint32_t digest[16];
77 bool digest_len_is_fixed;
88 .share0 = {0x43424140, 0x47464544, 0x4b4a4948, 0x4f4e4f4c,
89 0x53525150, 0x57565554, 0x5b5a5958, 0x5f5e5d5c},
94 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
95 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
96 "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
97 "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
98 "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
99 "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
100 "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
101 "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
102 "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
103 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
104 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
105 "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
106 "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7",
108 .customization_string =
"My Tagged Application",
109 .customization_string_len = 21,
110 .digest = {0x1c73bed5, 0x73d74e95, 0x59bb4628, 0xe3a8e3db, 0x7ae7830f,
111 0x5944ff4b, 0xb4c2f1f2, 0xceb8ebec, 0xc601ba67, 0x57b88a2e,
112 0x9b492d8d, 0x6727bbd1, 0x90117868, 0x6a300a02, 0x1d28de97,
115 .digest_len_is_fixed =
false,
118 static const uint8_t kKeyShare1[] = {
119 0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f, 0x8f, 0x9f, 0xaf,
120 0xbf, 0xcf, 0xdf, 0xef, 0xff, 0x0a, 0x1a, 0x2a, 0x3a, 0x4a, 0x5a,
121 0x6a, 0x7a, 0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa,
131 .reseed_on_key_change =
false,
132 .force_masks =
false,
133 .ctrl_aux_lock =
false,
139 static inline uint32_t aes_spin_until(uint32_t bit) {
155 crypto_fi_aes_mode_t uj_data;
156 TRY(ujson_deserialize_crypto_fi_aes_mode_t(uj, &uj_data));
160 pentest_clear_sensor_recov_alerts();
165 if (uj_data.key_trigger) {
166 pentest_set_trigger_high();
168 TRY(
dif_aes_start(&aes, &transaction, &aes_key_shares, NULL));
173 if (uj_data.key_trigger) {
174 pentest_set_trigger_low();
182 if (uj_data.plaintext_trigger) {
183 pentest_set_trigger_high();
186 if (uj_data.plaintext_trigger) {
187 pentest_set_trigger_low();
192 if (uj_data.encrypt_trigger) {
193 pentest_set_trigger_high();
202 if (uj_data.encrypt_trigger) {
203 pentest_set_trigger_low();
209 if (uj_data.ciphertext_trigger) {
210 pentest_set_trigger_high();
213 if (uj_data.ciphertext_trigger) {
214 pentest_set_trigger_low();
218 reg_alerts = pentest_get_triggered_alerts();
223 dif_rv_core_ibex_error_status_t codes;
224 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
227 crypto_fi_aes_ciphertext_t uj_output;
228 uj_output.err_status = codes;
229 memcpy(uj_output.ciphertext, ciphertext.data, 16);
230 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
231 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
232 sizeof(sensor_alerts.alerts));
233 RESP_OK(ujson_serialize_crypto_fi_aes_ciphertext_t, uj, &uj_output);
238 penetrationtest_cpuctrl_t uj_data;
239 TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));
241 pentest_select_trigger_type(kPentestTriggerTypeSw);
242 pentest_init(kPentestTriggerSourceAes,
243 kPentestPeripheralIoDiv4 | kPentestPeripheralAes |
244 kPentestPeripheralKmac | kPentestPeripheralEdn |
245 kPentestPeripheralCsrng | kPentestPeripheralEntropy);
248 pentest_configure_alert_handler();
251 penetrationtest_device_info_t uj_output;
252 TRY(pentest_configure_cpu(
253 uj_data.icache_disable, uj_data.dummy_instr_disable,
254 uj_data.enable_jittery_clock, uj_data.enable_sram_readback,
255 &uj_output.clock_jitter_locked, &uj_output.clock_jitter_en,
256 &uj_output.sram_main_readback_locked, &uj_output.sram_ret_readback_locked,
257 &uj_output.sram_main_readback_en, &uj_output.sram_ret_readback_en));
264 uint8_t key_share0[
sizeof(kAesModesKey256)];
265 for (
int i = 0; i <
sizeof(kAesModesKey256); ++i) {
266 key_share0[i] = kAesModesKey256[i] ^ kKeyShare1[i];
272 memcpy(aes_plaintext.data, kAesModesPlainText,
sizeof(aes_plaintext.data));
280 .entropy_seed = {0xaa25b4bf, 0x48ce8fff, 0x5a78282a, 0x48465647,
291 TRY(dif_rv_core_ibex_init(
296 TRY(pentest_read_device_id(uj_output.device_id));
297 RESP_OK(ujson_serialize_penetrationtest_device_info_t, uj, &uj_output);
304 crypto_fi_kmac_mode_t uj_data;
305 TRY(ujson_deserialize_crypto_fi_kmac_mode_t(uj, &uj_data));
309 pentest_clear_sensor_recov_alerts();
314 if (uj_data.key_trigger) {
315 pentest_set_trigger_high();
319 kKmacTestVector.mode, 0, &kKmacTestVector.key,
321 if (uj_data.key_trigger) {
322 pentest_set_trigger_low();
326 if (uj_data.absorb_trigger) {
327 pentest_set_trigger_high();
329 TRY(
dif_kmac_absorb(&kmac, &kmac_operation_state, kKmacTestVector.message,
330 kKmacTestVector.message_len, NULL));
331 if (uj_data.absorb_trigger) {
332 pentest_set_trigger_low();
336 if (uj_data.static_trigger) {
337 pentest_set_trigger_high();
342 if (uj_data.static_trigger) {
343 pentest_set_trigger_low();
347 uint32_t digest[kKmacTestVector.digest_len];
348 if (uj_data.squeeze_trigger) {
349 pentest_set_trigger_high();
352 kKmacTestVector.digest_len, NULL,
354 if (uj_data.squeeze_trigger) {
355 pentest_set_trigger_low();
361 uint32_t digest_2nd[kKmacTestVector.digest_len];
363 kKmacTestVector.digest_len, NULL,
367 reg_alerts = pentest_get_triggered_alerts();
374 dif_rv_core_ibex_error_status_t codes;
375 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
378 crypto_fi_kmac_digest_t uj_output;
379 uj_output.err_status = codes;
380 memcpy(uj_output.digest, (uint8_t *)digest, 8);
381 memcpy(uj_output.digest_2nd, (uint8_t *)digest_2nd, 8);
382 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
383 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
384 sizeof(sensor_alerts.alerts));
385 RESP_OK(ujson_serialize_crypto_fi_kmac_digest_t, uj, &uj_output);
391 crypto_fi_kmac_mode_t uj_data;
392 TRY(ujson_deserialize_crypto_fi_kmac_mode_t(uj, &uj_data));
396 pentest_clear_sensor_recov_alerts();
401 kKmacTestVector.mode, 0, &kKmacTestVector.key,
404 TRY(
dif_kmac_absorb(&kmac, &kmac_operation_state, kKmacTestVector.message,
405 kKmacTestVector.message_len, NULL));
408 uint32_t digest[kKmacTestVector.digest_len];
410 kKmacTestVector.digest_len, NULL,
414 pentest_set_trigger_high();
418 pentest_set_trigger_low();
421 reg_alerts = pentest_get_triggered_alerts();
426 dif_rv_core_ibex_error_status_t codes;
427 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
430 crypto_fi_kmac_state_t uj_output;
433 ptrdiff_t offset = KMAC_STATE_REG_OFFSET;
434 for (
size_t i = 0; i < 200; i++) {
435 uj_output.share0[i] = mmio_region_read8(base, offset);
436 uj_output.share1[i] =
438 offset +=
sizeof(uint8_t);
441 uj_output.err_status = codes;
442 memcpy(uj_output.digest, (uint8_t *)digest, 8);
443 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
444 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
445 sizeof(sensor_alerts.alerts));
447 RESP_OK(ujson_serialize_crypto_fi_kmac_state_t, uj, &uj_output);
457 pentest_clear_sensor_recov_alerts();
459 crypto_fi_test_result_mult_t uj_output;
462 uint32_t ctrl_reg_kmac = KMAC_CFG_SHADOWED_REG_RESVAL;
464 KMAC_CFG_SHADOWED_MSG_ENDIANNESS_BIT, 1);
466 ctrl_reg_kmac, KMAC_CFG_SHADOWED_STATE_ENDIANNESS_BIT, 1);
470 ctrl_reg_kmac, KMAC_CFG_SHADOWED_ENTROPY_FAST_PROCESS_BIT, 0);
474 KMAC_CFG_SHADOWED_ENTROPY_READY_BIT, 0);
476 ctrl_reg_kmac, KMAC_CFG_SHADOWED_EN_UNSUPPORTED_MODESTRENGTH_BIT, 1);
478 uint32_t ctrl_reg_kmac_addr =
481 pentest_set_trigger_high();
483 SHADOW_REG_ACCESS_10(ctrl_reg_kmac_addr, ctrl_reg_kmac)
484 SHADOW_REG_ACCESS_10(ctrl_reg_kmac_addr, ctrl_reg_kmac)
485 SHADOW_REG_ACCESS_10(ctrl_reg_kmac_addr, ctrl_reg_kmac)
487 pentest_set_trigger_low();
490 reg_alerts = pentest_get_triggered_alerts();
495 dif_rv_core_ibex_error_status_t codes;
496 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
500 KMAC_CFG_SHADOWED_REG_OFFSET);
501 uj_output.result[0] = ctrl_reg_kmac_read;
503 uj_output.result[1] = 0;
504 uj_output.result[2] = 0;
506 uj_output.err_status = codes;
507 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
508 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
509 sizeof(sensor_alerts.alerts));
510 RESP_OK(ujson_serialize_crypto_fi_test_result_mult_t, uj, &uj_output);
519 pentest_clear_sensor_recov_alerts();
521 crypto_fi_test_result_mult_t uj_output;
524 uint32_t ctrl_reg_aes_init = AES_CTRL_SHADOWED_REG_RESVAL;
527 AES_CTRL_SHADOWED_KEY_LEN_VALUE_AES_128);
530 AES_CTRL_SHADOWED_MODE_VALUE_AES_ECB);
532 ctrl_reg_aes_init, AES_CTRL_SHADOWED_PRNG_RESEED_RATE_FIELD,
533 AES_CTRL_SHADOWED_PRNG_RESEED_RATE_VALUE_PER_64);
535 ctrl_reg_aes_init, AES_CTRL_SHADOWED_SIDELOAD_BIT,
true);
537 ctrl_reg_aes_init, AES_CTRL_SHADOWED_OPERATION_FIELD,
538 AES_CTRL_SHADOWED_OPERATION_VALUE_AES_DEC);
540 ctrl_reg_aes_init, AES_CTRL_SHADOWED_MANUAL_OPERATION_BIT,
true);
541 abs_mmio_write32_shadowed(
544 aes_spin_until(AES_STATUS_IDLE_BIT);
546 uint32_t ctrl_reg_kmac_init = KMAC_CFG_SHADOWED_REG_RESVAL;
548 ctrl_reg_kmac_init, KMAC_CFG_SHADOWED_MSG_ENDIANNESS_BIT, 0);
550 ctrl_reg_kmac_init, KMAC_CFG_SHADOWED_STATE_ENDIANNESS_BIT, 0);
552 KMAC_CFG_SHADOWED_SIDELOAD_BIT, 0);
554 ctrl_reg_kmac_init, KMAC_CFG_SHADOWED_ENTROPY_FAST_PROCESS_BIT, 1);
556 KMAC_CFG_SHADOWED_MSG_MASK_BIT, 0);
558 ctrl_reg_kmac_init, KMAC_CFG_SHADOWED_ENTROPY_READY_BIT, 1);
560 ctrl_reg_kmac_init, KMAC_CFG_SHADOWED_EN_UNSUPPORTED_MODESTRENGTH_BIT, 0);
561 abs_mmio_write32_shadowed(
565 pentest_set_trigger_high();
568 AES_CTRL_SHADOWED_REG_OFFSET);
570 KMAC_CFG_SHADOWED_REG_OFFSET);
572 pentest_set_trigger_low();
575 reg_alerts = pentest_get_triggered_alerts();
580 dif_rv_core_ibex_error_status_t codes;
581 TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
584 uj_output.result[0] = 0;
585 if (ctrl_reg_aes_read != ctrl_reg_aes_init) {
586 uj_output.result[0] = ctrl_reg_aes_read;
589 uj_output.result[1] = 0;
590 if (ctrl_reg_kmac_read != ctrl_reg_kmac_init) {
591 uj_output.result[1] = ctrl_reg_kmac_read;
594 uj_output.result[2] = 0;
596 uj_output.err_status = codes;
597 memcpy(uj_output.alerts, reg_alerts.alerts,
sizeof(reg_alerts.alerts));
598 memcpy(uj_output.ast_alerts, sensor_alerts.alerts,
599 sizeof(sensor_alerts.alerts));
600 RESP_OK(ujson_serialize_crypto_fi_test_result_mult_t, uj, &uj_output);
606 crypto_fi_subcommand_t cmd;
607 TRY(ujson_deserialize_crypto_fi_subcommand_t(uj, &cmd));
609 case kCryptoFiSubcommandAes:
610 return handle_crypto_fi_aes(uj);
611 case kCryptoFiSubcommandInit:
612 return handle_crypto_fi_init(uj);
613 case kCryptoFiSubcommandKmac:
614 return handle_crypto_fi_kmac(uj);
615 case kCryptoFiSubcommandKmacState:
616 return handle_crypto_fi_kmac_state(uj);
617 case kCryptoFiSubcommandShadowRegAccess:
618 return handle_crypto_fi_shadow_reg_access(uj);
619 case kCryptoFiSubcommandShadowRegRead:
620 return handle_crypto_fi_shadow_reg_read(uj);
622 LOG_ERROR(
"Unrecognized Crypto FI subcommand: %d", cmd);
623 return INVALID_ARGUMENT();