13 #include "kmac_regs.h"
33 kDifKmacMaximumBitRate = 1600 - (2 * 128),
38 if ((data == NULL && len != 0) || out == NULL) {
47 "length requires more than 3 bytes to left encode");
49 "buffer is not large enough");
52 uint16_t bits = ((uint16_t)len) * 8;
53 char *buffer = out->
buffer;
54 if (bits <= UINT8_MAX) {
57 *buffer++ = (char)bits;
62 *buffer++ = (char)(bits >> 8);
63 *buffer++ = (char)bits;
73 if ((data == NULL && len != 0) || out == NULL) {
82 "length requires more than 2 bytes to left encode");
84 "buffer is not large enough");
91 out->
buffer[1] = (char)(len * 8);
106 static bool is_state_idle(
const dif_kmac_t *kmac) {
107 uint32_t reg = mmio_region_read32(kmac->
base_addr, KMAC_STATUS_REG_OFFSET);
120 static bool is_state_absorb(
const dif_kmac_t *kmac) {
121 uint32_t reg = mmio_region_read32(kmac->
base_addr, KMAC_STATUS_REG_OFFSET);
132 static bool is_state_squeeze(
const dif_kmac_t *kmac) {
133 uint32_t reg = mmio_region_read32(kmac->
base_addr, KMAC_STATUS_REG_OFFSET);
142 mmio_region_read32(kmac->
base_addr, KMAC_INTR_STATE_REG_OFFSET);
153 mmio_region_write32(kmac->
base_addr, KMAC_INTR_STATE_REG_OFFSET, reg);
159 uint32_t reg = mmio_region_read32(kmac->
base_addr, KMAC_STATUS_REG_OFFSET);
178 uint32_t entropy_mode_value;
179 bool entropy_ready =
false;
181 case kDifKmacEntropyModeIdle:
182 entropy_mode_value = KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_IDLE_MODE;
184 case kDifKmacEntropyModeEdn:
185 entropy_mode_value = KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_EDN_MODE;
186 entropy_ready =
true;
188 case kDifKmacEntropyModeSoftware:
189 entropy_mode_value = KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_SW_MODE;
190 entropy_ready =
true;
197 if (!is_state_idle(kmac)) {
202 uint32_t entropy_period_reg = 0;
204 entropy_period_reg, KMAC_ENTROPY_PERIOD_WAIT_TIMER_FIELD,
207 entropy_period_reg, KMAC_ENTROPY_PERIOD_PRESCALER_FIELD,
210 mmio_region_write32(kmac->
base_addr, KMAC_ENTROPY_PERIOD_REG_OFFSET,
214 uint32_t entropy_threshold_reg =
215 KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_REG_RESVAL;
217 entropy_threshold_reg,
218 KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_THRESHOLD_FIELD,
221 mmio_region_write32_shadowed(
222 kmac->
base_addr, KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_REG_OFFSET,
223 entropy_threshold_reg);
226 uint32_t cfg_reg = 0;
233 cfg_reg, KMAC_CFG_SHADOWED_ENTROPY_MODE_FIELD, entropy_mode_value);
245 mmio_region_write32_shadowed(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET,
250 mmio_region_write32(kmac->
base_addr, KMAC_ENTROPY_SEED_REG_OFFSET,
263 static uint32_t calculate_rate_bits(uint32_t security_level) {
269 return 1600 - 2 * security_level;
275 if (kmac == NULL || operation_state == NULL) {
284 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L224;
285 operation_state->
offset = 0;
286 operation_state->
r = calculate_rate_bits(224) / 32;
287 operation_state->
d = 224 / 32;
290 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
291 operation_state->
offset = 0;
292 operation_state->
r = calculate_rate_bits(256) / 32;
293 operation_state->
d = 256 / 32;
296 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L384;
297 operation_state->
offset = 0;
298 operation_state->
r = calculate_rate_bits(384) / 32;
299 operation_state->
d = 384 / 32;
302 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L512;
303 operation_state->
offset = 0;
304 operation_state->
r = calculate_rate_bits(512) / 32;
305 operation_state->
d = 512 / 32;
312 if (!is_state_idle(kmac)) {
321 mmio_region_read32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET);
325 KMAC_CFG_SHADOWED_MODE_VALUE_SHA3);
326 mmio_region_write32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
327 mmio_region_write32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
332 mmio_region_write32(kmac->
base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
341 if (kmac == NULL || operation_state == NULL) {
349 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128;
350 operation_state->
r = calculate_rate_bits(128) / 32;
353 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
354 operation_state->
r = calculate_rate_bits(256) / 32;
361 if (!is_state_idle(kmac)) {
366 operation_state->
d = 0;
367 operation_state->
offset = 0;
371 mmio_region_read32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET);
375 KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE);
376 mmio_region_write32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
377 mmio_region_write32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
382 mmio_region_write32(kmac->
base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
391 if (kmac == NULL || operation_state == NULL) {
396 bool n_is_empty = n == NULL || (n->
buffer[0] == 1 && n->
buffer[1] == 0);
397 bool s_is_empty = s == NULL || (s->
buffer[0] == 1 && s->
buffer[1] == 0);
398 if (n_is_empty && s_is_empty) {
415 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128;
416 operation_state->
r = calculate_rate_bits(128) / 32;
419 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
420 operation_state->
r = calculate_rate_bits(256) / 32;
427 if (!is_state_idle(kmac)) {
432 operation_state->
d = 0;
433 operation_state->
offset = 0;
437 mmio_region_read32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET);
441 KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE);
442 mmio_region_write32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
443 mmio_region_write32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
446 uint32_t prefix_regs[11] = {0};
447 uint8_t *prefix_data = (uint8_t *)prefix_regs;
448 if (n == NULL || n->
length < 3) {
457 if (s == NULL || s->
length == 0) {
467 mmio_region_write32(base, KMAC_PREFIX_0_REG_OFFSET, prefix_regs[0]);
468 mmio_region_write32(base, KMAC_PREFIX_1_REG_OFFSET, prefix_regs[1]);
469 mmio_region_write32(base, KMAC_PREFIX_2_REG_OFFSET, prefix_regs[2]);
470 mmio_region_write32(base, KMAC_PREFIX_3_REG_OFFSET, prefix_regs[3]);
471 mmio_region_write32(base, KMAC_PREFIX_4_REG_OFFSET, prefix_regs[4]);
472 mmio_region_write32(base, KMAC_PREFIX_5_REG_OFFSET, prefix_regs[5]);
473 mmio_region_write32(base, KMAC_PREFIX_6_REG_OFFSET, prefix_regs[6]);
474 mmio_region_write32(base, KMAC_PREFIX_7_REG_OFFSET, prefix_regs[7]);
475 mmio_region_write32(base, KMAC_PREFIX_8_REG_OFFSET, prefix_regs[8]);
476 mmio_region_write32(base, KMAC_PREFIX_9_REG_OFFSET, prefix_regs[9]);
477 mmio_region_write32(base, KMAC_PREFIX_10_REG_OFFSET, prefix_regs[10]);
482 mmio_region_write32(kmac->
base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
491 if (kmac == NULL || operation_state == NULL || k == NULL ||
500 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128;
501 operation_state->
r = calculate_rate_bits(128) / 32;
504 kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
505 operation_state->
r = calculate_rate_bits(256) / 32;
511 operation_state->
offset = 0;
512 operation_state->
d = l;
518 key_len = KMAC_KEY_LEN_LEN_VALUE_KEY128;
521 key_len = KMAC_KEY_LEN_LEN_VALUE_KEY192;
524 key_len = KMAC_KEY_LEN_LEN_VALUE_KEY256;
527 key_len = KMAC_KEY_LEN_LEN_VALUE_KEY384;
530 key_len = KMAC_KEY_LEN_LEN_VALUE_KEY512;
537 if (!is_state_idle(kmac)) {
541 mmio_region_write32(kmac->
base_addr, KMAC_KEY_LEN_REG_OFFSET, key_len);
542 for (
int i = 0; i <
ARRAYSIZE(k->share0); ++i) {
544 KMAC_KEY_SHARE0_0_REG_OFFSET +
545 (ptrdiff_t)i * (ptrdiff_t)
sizeof(uint32_t),
548 KMAC_KEY_SHARE1_0_REG_OFFSET +
549 (ptrdiff_t)i * (ptrdiff_t)
sizeof(uint32_t),
555 mmio_region_read32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET);
560 KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE);
561 mmio_region_write32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
562 mmio_region_write32(kmac->
base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
567 uint32_t prefix_regs[11] = {
574 if (s != NULL && s->
length >= 3) {
576 prefix_regs[1] &= 0xFFFF;
577 prefix_regs[1] |= (uint32_t)((uint8_t)s->
buffer[0]) << 16;
578 prefix_regs[1] |= (uint32_t)((uint8_t)s->
buffer[1]) << 24;
584 mmio_region_write32(base, KMAC_PREFIX_0_REG_OFFSET, prefix_regs[0]);
585 mmio_region_write32(base, KMAC_PREFIX_1_REG_OFFSET, prefix_regs[1]);
586 mmio_region_write32(base, KMAC_PREFIX_2_REG_OFFSET, prefix_regs[2]);
587 mmio_region_write32(base, KMAC_PREFIX_3_REG_OFFSET, prefix_regs[3]);
588 mmio_region_write32(base, KMAC_PREFIX_4_REG_OFFSET, prefix_regs[4]);
589 mmio_region_write32(base, KMAC_PREFIX_5_REG_OFFSET, prefix_regs[5]);
590 mmio_region_write32(base, KMAC_PREFIX_6_REG_OFFSET, prefix_regs[6]);
591 mmio_region_write32(base, KMAC_PREFIX_7_REG_OFFSET, prefix_regs[7]);
592 mmio_region_write32(base, KMAC_PREFIX_8_REG_OFFSET, prefix_regs[8]);
593 mmio_region_write32(base, KMAC_PREFIX_9_REG_OFFSET, prefix_regs[9]);
594 mmio_region_write32(base, KMAC_PREFIX_10_REG_OFFSET, prefix_regs[10]);
599 mmio_region_write32(kmac->
base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
604 static void msg_fifo_write(
const dif_kmac_t *kmac,
const unsigned char *data,
609 for (; len != 0 && ((uintptr_t)data) %
sizeof(uint32_t); --len) {
610 mmio_region_write8(kmac->
base_addr, KMAC_MSG_FIFO_REG_OFFSET, *data++);
612 for (; len >=
sizeof(uint32_t); len -=
sizeof(uint32_t)) {
613 mmio_region_write32(kmac->
base_addr, KMAC_MSG_FIFO_REG_OFFSET,
615 data +=
sizeof(uint32_t);
617 for (; len != 0; --len) {
618 mmio_region_write8(kmac->
base_addr, KMAC_MSG_FIFO_REG_OFFSET, *data++);
624 const void *msg,
size_t len,
size_t *processed) {
626 if (processed != NULL) {
630 if (kmac == NULL || operation_state == NULL || (msg == NULL && len != 0)) {
635 if (operation_state->
r == 0) {
640 if (!is_state_absorb(kmac)) {
647 const unsigned char *data = (
const unsigned char *)msg;
655 size_t free_entries = (KMAC_PARAM_NUM_ENTRIES_MSG_FIFO -
status.fifo_depth);
656 size_t max_len = free_entries * KMAC_PARAM_NUM_BYTES_MSG_FIFO_ENTRY;
657 size_t write_len = (len < max_len) ? len : max_len;
658 msg_fifo_write(kmac, data, write_len);
664 if (processed != NULL) {
665 *processed = write_len;
675 uint32_t *out,
size_t len,
size_t *processed,
676 uint32_t *capacity) {
677 if (kmac == NULL || operation_state == NULL || (out == NULL && len != 0)) {
682 if (processed != NULL) {
697 uint32_t d = operation_state->
d * 32;
698 int len = 1 + (d > 0xFF) + (d > 0xFFFF) + (d > 0xFFFFFF);
699 int shift = (len - 1) * 8;
701 mmio_region_write8(base, KMAC_MSG_FIFO_REG_OFFSET,
702 (uint8_t)(d >> shift));
705 mmio_region_write8(base, KMAC_MSG_FIFO_REG_OFFSET, (uint8_t)d);
706 mmio_region_write8(base, KMAC_MSG_FIFO_REG_OFFSET, (uint8_t)len);
712 KMAC_CMD_CMD_VALUE_PROCESS);
713 mmio_region_write32(base, KMAC_CMD_REG_OFFSET, cmd_reg);
718 if (operation_state->
d != 0 &&
719 len > (operation_state->
d - operation_state->
offset)) {
729 size_t remaining = operation_state->
r - operation_state->
offset;
730 if (operation_state->
d != 0 && operation_state->
d < operation_state->
r) {
731 remaining = operation_state->
d - operation_state->
offset;
738 if (operation_state->
d != 0) {
739 if (operation_state->
d <= operation_state->
r) {
742 operation_state->
d -= operation_state->
r;
748 mmio_region_write32(base, KMAC_CMD_REG_OFFSET, cmd_reg);
749 operation_state->
offset = 0;
758 KMAC_STATE_REG_OFFSET +
759 (ptrdiff_t)operation_state->
offset * (ptrdiff_t)
sizeof(uint32_t);
760 for (
size_t i = 0; i < n; ++i) {
762 uint32_t share0 = mmio_region_read32(base, offset);
765 *out++ = share0 ^ share1;
766 offset +=
sizeof(uint32_t);
768 operation_state->
offset += n;
770 if (processed != NULL) {
776 if (capacity != NULL) {
777 ptrdiff_t capacity_offset =
778 KMAC_STATE_REG_OFFSET +
779 (ptrdiff_t)operation_state->
r * (ptrdiff_t)
sizeof(uint32_t);
781 uint32_t share0 = mmio_region_read32(base, capacity_offset);
782 uint32_t share1 = mmio_region_read32(
784 *capacity++ = share0 ^ share1;
785 capacity_offset +=
sizeof(uint32_t);
794 if (kmac == NULL || operation_state == NULL) {
804 if (is_state_squeeze(kmac)) {
813 mmio_region_write32(kmac->
base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
818 operation_state->
offset = 0;
819 operation_state->
r = 0;
820 operation_state->
d = 0;
827 if (kmac == NULL || is_locked == NULL) {
832 mmio_region_read32(kmac->
base_addr, KMAC_CFG_REGWEN_REG_OFFSET);
839 if (kmac == NULL || kmac_status == NULL) {
843 uint32_t reg = mmio_region_read32(kmac->
base_addr, KMAC_STATUS_REG_OFFSET);
858 .index = KMAC_STATUS_ALERT_FATAL_FAULT_BIT});
864 uint32_t *hash_ctr) {
865 if (kmac == NULL || hash_ctr == NULL) {
869 uint32_t reg = mmio_region_read32(kmac->
base_addr,
870 KMAC_ENTROPY_REFRESH_HASH_CNT_REG_OFFSET);
880 if (kmac == NULL || error == NULL || info == NULL) {
884 uint32_t reg = mmio_region_read32(kmac->
base_addr, KMAC_ERR_CODE_REG_OFFSET);
885 *info = reg & 0xFFFFFF;
886 *error = (reg >> 24) & 0xFF;
892 if (kmac == NULL || operation_state == NULL) {
895 operation_state->
d = 0;
896 operation_state->
r = 0;
897 operation_state->
offset = 0;
909 mmio_region_write32(kmac->
base_addr, KMAC_CMD_REG_OFFSET, reg);