5 #include "sw/device/tests/penetrationtests/firmware/sca/sha3_sca.h"
8 #include "sw/device/lib/base/status.h"
11 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
12 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
13 #include "sw/device/lib/ujson/ujson.h"
15 #include "sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h"
16 #include "sw/device/tests/penetrationtests/json/commands.h"
17 #include "sw/device/tests/penetrationtests/json/sha3_sca_commands.h"
20 #include "kmac_regs.h"
44 kIbexSha3SleepCycles = 1060,
49 kIbexLoadHashMessageSleepCycles = 500,
53 kNumBatchOpsMax = 128,
59 static bool fpga_mode =
false;
64 static dif_kmac_t kmac;
72 .entropy_seed = {0xb153e3fe, 0x09596819, 0x3e85a6e8, 0xb6dcdaba, 0x50dc409c,
91 uint8_t message_fixed[kMessageLength];
99 static bool run_fixed =
false;
104 uint8_t sha3_batch_messages[kNumBatchOpsMax][kMessageLength];
109 static void kmac_block_until_idle(
void) {
113 reg = mmio_region_read32(kmac.base_addr, KMAC_STATUS_REG_OFFSET);
120 static void kmac_reset(
void) {
123 kmac.base_addr, KMAC_CMD_REG_OFFSET,
125 kmac_block_until_idle();
136 static bool is_state_idle(
void) {
137 uint32_t reg = mmio_region_read32(kmac.base_addr, KMAC_STATUS_REG_OFFSET);
147 static uint32_t calculate_rate_bits(uint32_t security_level) {
153 return 1600 - 2 * security_level;
170 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L224;
171 kmac_operation_state.
offset = 0;
172 kmac_operation_state.
r = calculate_rate_bits(224) / 32;
173 kmac_operation_state.
d = 224 / 32;
176 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
177 kmac_operation_state.
offset = 0;
178 kmac_operation_state.
r = calculate_rate_bits(256) / 32;
179 kmac_operation_state.
d = 256 / 32;
182 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L384;
183 kmac_operation_state.
offset = 0;
184 kmac_operation_state.
r = calculate_rate_bits(384) / 32;
185 kmac_operation_state.
d = 384 / 32;
188 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L512;
189 kmac_operation_state.
offset = 0;
190 kmac_operation_state.
r = calculate_rate_bits(512) / 32;
191 kmac_operation_state.
d = 512 / 32;
198 if (!is_state_idle()) {
203 kmac_operation_state.
append_d =
false;
207 mmio_region_read32(kmac.base_addr, KMAC_CFG_SHADOWED_REG_OFFSET);
211 KMAC_CFG_SHADOWED_MODE_VALUE_SHA3);
212 mmio_region_write32(kmac.base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
213 mmio_region_write32(kmac.base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
228 static dif_result_t sha3_msg_write(
const void *msg,
size_t msg_len,
231 if (processed != NULL) {
235 if (msg == NULL && msg_len != 0) {
240 if (kmac_operation_state.
r == 0) {
248 for (
size_t i = 0; i < msg_len; ++i) {
249 mmio_region_write8(kmac.base_addr, KMAC_MSG_FIFO_REG_OFFSET,
250 ((
const uint8_t *)msg)[i]);
253 if (processed != NULL) {
254 *processed = msg_len;
266 static void kmac_process_cmd(
void) {
270 mmio_region_write32(kmac.base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
278 static void kmac_start_cmd(
void) {
282 mmio_region_write32(kmac.base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
290 static void kmac_start_process_cmd(
void) {
304 static void kmac_msg_done(
void) {
308 reg = mmio_region_read32(kmac.base_addr, KMAC_STATUS_REG_OFFSET);
321 static dif_result_t sha3_get_digest(uint32_t *out,
size_t len) {
322 if (out == NULL && len != 0) {
328 size_t remaining = kmac_operation_state.
r - kmac_operation_state.
offset;
329 if (kmac_operation_state.
d != 0 &&
330 kmac_operation_state.
d < kmac_operation_state.
r) {
331 remaining = kmac_operation_state.
d - kmac_operation_state.
offset;
344 KMAC_STATE_REG_OFFSET +
345 (ptrdiff_t)kmac_operation_state.
offset * (ptrdiff_t)
sizeof(uint32_t);
346 for (
size_t i = 0; i < n; ++i) {
348 uint32_t share0 = mmio_region_read32(kmac.base_addr, offset);
351 *out++ = share0 ^ share1;
352 offset +=
sizeof(uint32_t);
354 kmac_operation_state.
offset += n;
366 cryptotest_sha3_sca_masks_off_t uj_data;
367 TRY(ujson_deserialize_cryptotest_sha3_sca_masks_off_t(uj, &uj_data));
371 if (uj_data.masks_off == 0x01) {
380 kmac_block_until_idle();
382 cryptotest_sha3_sca_status_t uj_status;
383 uj_status.status = 0;
384 RESP_OK(ujson_serialize_cryptotest_sha3_sca_status_t, uj, &uj_status);
396 sha3_sca_error_t sha3_serial_absorb(
const uint8_t *msg,
size_t msg_len) {
399 return sha3ScaAborted;
402 if (fpga_mode ==
false) {
409 if (sha3_msg_write(msg, msg_len, NULL) !=
kDifOk) {
410 return sha3ScaAborted;
419 pentest_call_and_sleep(kmac_start_process_cmd, kIbexSha3SleepCycles,
true,
424 pentest_call_and_sleep(kmac_process_cmd, kIbexLoadHashMessageSleepCycles,
443 cryptotest_sha3_sca_msg_t uj_msg;
444 TRY(ujson_deserialize_cryptotest_sha3_sca_msg_t(uj, &uj_msg));
445 if (uj_msg.msg_length != kMessageLength) {
446 return OUT_OF_RANGE();
450 if (sha3_serial_absorb(uj_msg.msg, uj_msg.msg_length) != sha3ScaOk) {
458 uint32_t out[kDigestLength];
459 if (sha3_get_digest(out, kDigestLength) !=
kDifOk) {
462 cryptotest_sha3_sca_batch_digest_t uj_output;
463 memcpy(uj_output.batch_digest, (uint8_t *)out, kDigestLength * 4);
464 RESP_OK(ujson_serialize_cryptotest_sha3_sca_batch_digest_t, uj, &uj_output);
485 cryptotest_sha3_sca_msg_t uj_msg;
486 TRY(ujson_deserialize_cryptotest_sha3_sca_msg_t(uj, &uj_msg));
488 if (uj_msg.msg_length != kMessageLength) {
489 return OUT_OF_RANGE();
492 memcpy(message_fixed, uj_msg.msg, uj_msg.msg_length);
508 penetrationtest_num_enc_t uj_data;
509 TRY(ujson_deserialize_penetrationtest_num_enc_t(uj, &uj_data));
511 uint32_t out[kDigestLength];
512 uint32_t batch_digest[kDigestLength];
513 uint8_t dummy_message[kMessageLength];
515 for (uint32_t j = 0; j < kDigestLength; ++j) {
519 for (uint32_t i = 0; i < uj_data.num_enc; ++i) {
521 memcpy(sha3_batch_messages[i], message_fixed, kMessageLength);
526 run_fixed = dummy_message[0] & 0x1;
529 for (uint32_t i = 0; i < uj_data.num_enc; ++i) {
532 if (sha3_serial_absorb(sha3_batch_messages[i], kMessageLength) !=
538 if (sha3_get_digest(out, kDigestLength) !=
kDifOk) {
545 for (uint32_t j = 0; j < kDigestLength; ++j) {
546 batch_digest[j] ^= out[j];
551 cryptotest_sha3_sca_status_t uj_status;
552 uj_status.status = 0;
553 RESP_OK(ujson_serialize_cryptotest_sha3_sca_status_t, uj, &uj_status);
555 cryptotest_sha3_sca_batch_digest_t uj_output;
556 memcpy(uj_output.batch_digest, (uint8_t *)batch_digest, kDigestLength * 4);
557 RESP_OK(ujson_serialize_cryptotest_sha3_sca_batch_digest_t, uj, &uj_output);
573 cryptotest_sha3_sca_lfsr_t uj_lfsr_data;
574 TRY(ujson_deserialize_cryptotest_sha3_sca_lfsr_t(uj, &uj_lfsr_data));
575 pentest_seed_lfsr(
read_32(uj_lfsr_data.seed), kPentestLfsrMasking);
590 cryptotest_sha3_sca_fpga_mode_t uj_data;
591 TRY(ujson_deserialize_cryptotest_sha3_sca_fpga_mode_t(uj, &uj_data));
592 if (uj_data.fpga_mode == 0x01) {
596 penetrationtest_cpuctrl_t uj_cpuctrl;
597 TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_cpuctrl));
599 pentest_init(kPentestTriggerSourceKmac,
600 kPentestPeripheralIoDiv4 | kPentestPeripheralKmac);
606 kmac_block_until_idle();
609 penetrationtest_device_info_t uj_output;
610 TRY(pentest_configure_cpu(
611 uj_cpuctrl.icache_disable, uj_cpuctrl.dummy_instr_disable,
612 uj_cpuctrl.enable_jittery_clock, uj_cpuctrl.enable_sram_readback,
613 &uj_output.clock_jitter_locked, &uj_output.clock_jitter_en,
614 &uj_output.sram_main_readback_locked, &uj_output.sram_ret_readback_locked,
615 &uj_output.sram_main_readback_en, &uj_output.sram_ret_readback_en));
618 TRY(pentest_read_device_id(uj_output.device_id));
619 RESP_OK(ujson_serialize_penetrationtest_device_info_t, uj, &uj_output);
632 sha3_sca_subcommand_t cmd;
633 TRY(ujson_deserialize_sha3_sca_subcommand_t(uj, &cmd));
635 case kSha3ScaSubcommandInit:
636 return handle_sha3_pentest_init(uj);
637 case kSha3ScaSubcommandSingleAbsorb:
638 return handle_sha3_sca_single_absorb(uj);
639 case kSha3ScaSubcommandBatch:
640 return handle_sha3_sca_batch(uj);
641 case kSha3ScaSubcommandFixedMessageSet:
642 return handle_sha3_sca_fixed_message_set(uj);
643 case kSha3ScaSubcommandSeedLfsr:
644 return handle_sha3_pentest_seed_lfsr(uj);
645 case kSha3ScaSubcommandDisableMasking:
646 return handle_sha3_sca_disable_masking(uj);
648 LOG_ERROR(
"Unrecognized SHA SCA FI subcommand: %d", cmd);
649 return INVALID_ARGUMENT();