5 #include "sw/device/lib/crypto/drivers/kmac.h"
10 #include "sw/device/lib/crypto/drivers/entropy.h"
11 #include "sw/device/lib/crypto/impl/status.h"
14 #include "kmac_regs.h"
17 #define MODULE_ID MAKE_MODULE_ID('d', 'k', 'c')
24 typedef enum kmac_security_str {
25 kKmacSecurityStrength128 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128,
26 kKmacSecurityStrength224 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L224,
27 kKmacSecurityStrength256 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256,
28 kKmacSecurityStrength384 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L384,
29 kKmacSecurityStrength512 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L512,
30 } kmac_security_str_t;
40 typedef enum kmac_operation {
41 kKmacOperationSHA3 = KMAC_CFG_SHADOWED_MODE_VALUE_SHA3 << 1 | 0,
42 kKmacOperationSHAKE = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE << 1 | 0,
43 kKmacOperationCSHAKE = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE << 1 | 0,
44 kKmacOperationKMAC = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE << 1 | 1,
50 typedef enum kmac_key_length {
51 kKmacKeyLength128 = KMAC_KEY_LEN_LEN_VALUE_KEY128,
52 kKmacKeyLength192 = KMAC_KEY_LEN_LEN_VALUE_KEY192,
53 kKmacKeyLength256 = KMAC_KEY_LEN_LEN_VALUE_KEY256,
54 kKmacKeyLength384 = KMAC_KEY_LEN_LEN_VALUE_KEY384,
55 kKmacKeyLength512 = KMAC_KEY_LEN_LEN_VALUE_KEY512,
59 kKmacPrefixRegCount = 4 * KMAC_PREFIX_MULTIREG_COUNT,
61 kKmacCfgAddr = kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET,
62 kKmacKeyShare0Addr = kKmacBaseAddr + KMAC_KEY_SHARE0_0_REG_OFFSET,
63 kKmacKeyShare1Addr = kKmacBaseAddr + KMAC_KEY_SHARE1_0_REG_OFFSET,
64 kKmacStateShareSize = KMAC_STATE_SIZE_BYTES / 2,
65 kKmacStateShare0Addr = kKmacBaseAddr + KMAC_STATE_REG_OFFSET,
66 kKmacStateShare1Addr =
67 kKmacBaseAddr + KMAC_STATE_REG_OFFSET + kKmacStateShareSize,
71 static const uint8_t kKmacFuncNameKMAC[] = {0x4b, 0x4d, 0x41, 0x43};
78 static const uint32_t prefix_offsets[] = {
79 KMAC_PREFIX_0_REG_OFFSET, KMAC_PREFIX_1_REG_OFFSET,
80 KMAC_PREFIX_2_REG_OFFSET, KMAC_PREFIX_3_REG_OFFSET,
81 KMAC_PREFIX_4_REG_OFFSET, KMAC_PREFIX_5_REG_OFFSET,
82 KMAC_PREFIX_6_REG_OFFSET, KMAC_PREFIX_7_REG_OFFSET,
83 KMAC_PREFIX_8_REG_OFFSET, KMAC_PREFIX_9_REG_OFFSET,
84 KMAC_PREFIX_10_REG_OFFSET,
89 KMAC_KEY_SHARE0_0_REG_OFFSET + 4);
91 KMAC_KEY_SHARE0_1_REG_OFFSET + 4);
93 KMAC_KEY_SHARE0_2_REG_OFFSET + 4);
95 KMAC_KEY_SHARE0_3_REG_OFFSET + 4);
97 KMAC_KEY_SHARE0_4_REG_OFFSET + 4);
99 KMAC_KEY_SHARE0_5_REG_OFFSET + 4);
101 KMAC_KEY_SHARE0_6_REG_OFFSET + 4);
103 KMAC_KEY_SHARE0_7_REG_OFFSET + 4);
105 KMAC_KEY_SHARE0_8_REG_OFFSET + 4);
107 KMAC_KEY_SHARE0_9_REG_OFFSET + 4);
109 KMAC_KEY_SHARE0_10_REG_OFFSET + 4);
111 KMAC_KEY_SHARE0_11_REG_OFFSET + 4);
113 KMAC_KEY_SHARE0_12_REG_OFFSET + 4);
115 KMAC_KEY_SHARE0_13_REG_OFFSET + 4);
117 KMAC_KEY_SHARE0_14_REG_OFFSET + 4);
120 KMAC_KEY_SHARE1_0_REG_OFFSET + 4);
122 KMAC_KEY_SHARE1_1_REG_OFFSET + 4);
124 KMAC_KEY_SHARE1_2_REG_OFFSET + 4);
126 KMAC_KEY_SHARE1_3_REG_OFFSET + 4);
128 KMAC_KEY_SHARE1_4_REG_OFFSET + 4);
130 KMAC_KEY_SHARE1_5_REG_OFFSET + 4);
132 KMAC_KEY_SHARE1_6_REG_OFFSET + 4);
134 KMAC_KEY_SHARE1_7_REG_OFFSET + 4);
136 KMAC_KEY_SHARE1_8_REG_OFFSET + 4);
138 KMAC_KEY_SHARE1_9_REG_OFFSET + 4);
140 KMAC_KEY_SHARE1_10_REG_OFFSET + 4);
142 KMAC_KEY_SHARE1_11_REG_OFFSET + 4);
144 KMAC_KEY_SHARE1_12_REG_OFFSET + 4);
146 KMAC_KEY_SHARE1_13_REG_OFFSET + 4);
148 KMAC_KEY_SHARE1_14_REG_OFFSET + 4);
166 static status_t kmac_get_keccak_rate_words(kmac_security_str_t security_str,
167 size_t *keccak_rate) {
171 switch (security_str) {
172 case kKmacSecurityStrength128:
173 *keccak_rate = (1600 - 2 * 128) / 32;
175 case kKmacSecurityStrength224:
176 *keccak_rate = (1600 - 2 * 224) / 32;
178 case kKmacSecurityStrength256:
179 *keccak_rate = (1600 - 2 * 256) / 32;
181 case kKmacSecurityStrength384:
182 *keccak_rate = (1600 - 2 * 384) / 32;
184 case kKmacSecurityStrength512:
185 *keccak_rate = (1600 - 2 * 512) / 32;
188 return OTCRYPTO_BAD_ARGS;
203 static status_t kmac_get_key_len_bytes(
size_t key_len,
204 kmac_key_len_t *key_len_enum) {
207 *key_len_enum = kKmacKeyLength128;
210 *key_len_enum = kKmacKeyLength192;
213 *key_len_enum = kKmacKeyLength256;
216 *key_len_enum = kKmacKeyLength384;
219 *key_len_enum = kKmacKeyLength512;
222 return OTCRYPTO_BAD_ARGS;
227 status_t kmac_key_length_check(
size_t key_len) {
228 kmac_key_len_t key_len_enum;
231 return kmac_get_key_len_bytes(key_len, &key_len_enum);
234 status_t kmac_hwip_default_configure(
void) {
236 HARDENED_TRY(entropy_complex_check());
238 uint32_t status_reg = abs_mmio_read32(kKmacBaseAddr + KMAC_STATUS_REG_OFFSET);
242 return OTCRYPTO_FATAL_ERR;
245 KMAC_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_BIT)) {
246 return OTCRYPTO_RECOV_ERR;
250 return OTCRYPTO_RECOV_ERR;
254 uint32_t intr_state =
255 abs_mmio_read32(kKmacBaseAddr + KMAC_INTR_STATE_REG_OFFSET);
257 return OTCRYPTO_RECOV_ERR;
261 uint32_t cfg_regwen =
262 abs_mmio_read32(kKmacBaseAddr + KMAC_CFG_REGWEN_REG_OFFSET);
264 return OTCRYPTO_RECOV_ERR;
268 uint32_t intr_reg = KMAC_INTR_ENABLE_REG_RESVAL;
270 abs_mmio_write32(kKmacBaseAddr + KMAC_INTR_ENABLE_REG_OFFSET, intr_reg);
274 uint32_t entropy_period = KMAC_ENTROPY_PERIOD_REG_RESVAL;
276 entropy_period, KMAC_ENTROPY_PERIOD_PRESCALER_FIELD, UINT32_MAX);
278 entropy_period, KMAC_ENTROPY_PERIOD_WAIT_TIMER_FIELD, UINT32_MAX);
279 abs_mmio_write32(kKmacBaseAddr + KMAC_ENTROPY_PERIOD_REG_OFFSET,
284 uint32_t entropy_hash_threshold =
285 KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_REG_RESVAL;
287 entropy_hash_threshold,
288 KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_THRESHOLD_FIELD, UINT32_MAX);
290 kKmacBaseAddr + KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_REG_OFFSET,
291 entropy_hash_threshold);
294 uint32_t cfg_reg = KMAC_CFG_SHADOWED_REG_RESVAL;
307 KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_EDN_MODE);
311 KMAC_CFG_SHADOWED_ENTROPY_FAST_PROCESS_BIT, 1);
320 cfg_reg, KMAC_CFG_SHADOWED_EN_UNSUPPORTED_MODESTRENGTH_BIT, 0);
322 abs_mmio_write32_shadowed(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET,
338 static status_t wait_status_bit(uint32_t bit_position,
bool bit_value) {
339 if (bit_position > 31) {
340 return OTCRYPTO_BAD_ARGS;
344 uint32_t reg = abs_mmio_read32(kKmacBaseAddr + KMAC_STATUS_REG_OFFSET);
346 return OTCRYPTO_FATAL_ERR;
349 return OTCRYPTO_RECOV_ERR;
381 static status_t little_endian_encode(
size_t value, uint8_t *encoding_buf,
382 uint8_t *encoding_header) {
384 uint8_t reverse_buf[
sizeof(size_t)];
386 reverse_buf[len] = value & UINT8_MAX;
390 *encoding_header = len;
392 for (
size_t idx = 0; idx < len; idx++) {
393 encoding_buf[idx] = reverse_buf[len - 1 - idx];
411 static status_t kmac_set_prefix_regs(
const unsigned char *func_name,
412 size_t func_name_len,
413 const unsigned char *cust_str,
414 size_t cust_str_len) {
416 uint32_t prefix_buffer[kKmacPrefixRegCount] = {0x0};
417 unsigned char *prefix_buf_ptr = (
unsigned char *)prefix_buffer;
419 if (func_name_len + cust_str_len > kKmacPrefixMaxSize) {
420 return OTCRYPTO_BAD_ARGS;
424 uint8_t bytes_written = 0;
425 HARDENED_TRY(little_endian_encode(func_name_len << 3, prefix_buf_ptr + 1,
427 prefix_buf_ptr[0] = bytes_written;
428 prefix_buf_ptr += bytes_written + 1;
431 memcpy(prefix_buf_ptr, func_name, func_name_len);
432 prefix_buf_ptr += func_name_len;
435 HARDENED_TRY(little_endian_encode(cust_str_len << 3, prefix_buf_ptr + 1,
437 prefix_buf_ptr[0] = bytes_written;
438 prefix_buf_ptr += bytes_written + 1;
441 memcpy(prefix_buf_ptr, cust_str, cust_str_len);
444 for (
size_t i = 0; i < KMAC_PREFIX_MULTIREG_COUNT; i++) {
445 abs_mmio_write32(kKmacBaseAddr + prefix_offsets[i], prefix_buffer[i]);
476 static status_t kmac_init(kmac_operation_t operation,
477 kmac_security_str_t security_str,
479 HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_IDLE_BIT, 1));
483 if (operation == kKmacOperationKMAC) {
484 HARDENED_TRY(entropy_complex_check());
491 abs_mmio_read32(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET);
502 return OTCRYPTO_BAD_ARGS;
513 abs_mmio_write32_shadowed(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET,
538 static status_t kmac_write_prefix_block(kmac_operation_t operation,
539 const unsigned char *func_name,
540 size_t func_name_len,
541 const unsigned char *cust_str,
542 size_t cust_str_len) {
543 if (operation == kKmacOperationCSHAKE) {
544 return kmac_set_prefix_regs(func_name, func_name_len, cust_str,
546 }
else if (operation == kKmacOperationKMAC) {
547 return kmac_set_prefix_regs(kKmacFuncNameKMAC,
sizeof(kKmacFuncNameKMAC),
548 cust_str, cust_str_len);
550 return OTCRYPTO_BAD_ARGS;
567 kmac_key_len_t key_len_enum;
568 HARDENED_TRY(kmac_get_key_len_bytes(key->len, &key_len_enum));
571 KMAC_KEY_LEN_REG_RESVAL, KMAC_KEY_LEN_LEN_FIELD, key_len_enum);
572 abs_mmio_write32(kKmacBaseAddr + KMAC_KEY_LEN_REG_OFFSET, key_len_reg);
574 for (
size_t i = 0; i < key->len; i += 4) {
575 abs_mmio_write32(kKmacKeyShare0Addr + i, key->share0[i / 4]);
576 abs_mmio_write32(kKmacKeyShare1Addr + i, key->share1[i / 4]);
610 static status_t kmac_process_msg_blocks(kmac_operation_t operation,
611 const uint8_t *message,
612 size_t message_len, uint32_t *digest,
613 size_t digest_len_words,
616 HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_IDLE_BIT, 1));
620 uint32_t cmd_reg = KMAC_CMD_REG_RESVAL;
622 KMAC_CMD_CMD_VALUE_START);
623 abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);
624 HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_ABSORB_BIT, 1));
630 HARDENED_TRY(wait_status_bit(KMAC_STATUS_FIFO_FULL_BIT, 0));
631 abs_mmio_write8(kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET, message[i]);
635 for (; i +
sizeof(uint32_t) <= message_len; i +=
sizeof(uint32_t)) {
636 HARDENED_TRY(wait_status_bit(KMAC_STATUS_FIFO_FULL_BIT, 0));
637 uint32_t next_word =
read_32(&message[i]);
638 abs_mmio_write32(kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET, next_word);
642 for (; i < message_len; i++) {
643 HARDENED_TRY(wait_status_bit(KMAC_STATUS_FIFO_FULL_BIT, 0));
644 abs_mmio_write8(kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET, message[i]);
648 if (operation == kKmacOperationKMAC) {
649 uint32_t digest_len_bits = 8 *
sizeof(uint32_t) * digest_len_words;
650 if (digest_len_bits / (8 *
sizeof(uint32_t)) != digest_len_words) {
651 return OTCRYPTO_BAD_ARGS;
659 uint8_t buf[
sizeof(size_t) + 1] = {0};
660 uint8_t bytes_written;
661 HARDENED_TRY(little_endian_encode(digest_len_bits, buf, &bytes_written));
662 buf[bytes_written] = bytes_written;
663 uint8_t *fifo_dst = (uint8_t *)(kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET);
664 memcpy(fifo_dst, buf, bytes_written + 1);
668 cmd_reg = KMAC_CMD_REG_RESVAL;
670 KMAC_CMD_CMD_VALUE_PROCESS);
671 abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);
674 HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_SQUEEZE_BIT, 1));
677 abs_mmio_read32(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET);
678 uint32_t keccak_str =
680 size_t keccak_rate_words;
681 HARDENED_TRY(kmac_get_keccak_rate_words(keccak_str, &keccak_rate_words));
686 while (launder32(idx) < digest_len_words) {
692 HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_SQUEEZE_BIT, 1));
701 for (offset = 0; launder32(idx + offset) < digest_len_words &&
702 offset < keccak_rate_words;
704 digest[idx + offset] =
705 abs_mmio_read32(kKmacStateShare0Addr + offset *
sizeof(uint32_t));
707 for (offset = 0; launder32(idx + offset) < digest_len_words &&
708 offset < keccak_rate_words;
710 digest[idx + offset + digest_len_words] =
711 abs_mmio_read32(kKmacStateShare1Addr + offset *
sizeof(uint32_t));
721 for (; launder32(idx) < digest_len_words && offset < keccak_rate_words;
724 abs_mmio_read32(kKmacStateShare0Addr + offset *
sizeof(uint32_t));
726 abs_mmio_read32(kKmacStateShare1Addr + offset *
sizeof(uint32_t));
733 if (launder32(offset) == keccak_rate_words && idx < digest_len_words) {
735 cmd_reg = KMAC_CMD_REG_RESVAL;
737 KMAC_CMD_CMD_VALUE_RUN);
738 abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);
744 HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_SQUEEZE_BIT, 1));
747 cmd_reg = KMAC_CMD_REG_RESVAL;
749 KMAC_CMD_CMD_VALUE_DONE);
750 abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);
755 status_t kmac_sha3_224(
const uint8_t *message,
size_t message_len,
757 HARDENED_TRY(kmac_init(kKmacOperationSHA3, kKmacSecurityStrength224,
760 size_t digest_len_words = kSha3_224DigestWords;
761 return kmac_process_msg_blocks(kKmacOperationSHA3, message, message_len,
762 digest, digest_len_words,
766 status_t kmac_sha3_256(
const uint8_t *message,
size_t message_len,
768 HARDENED_TRY(kmac_init(kKmacOperationSHA3, kKmacSecurityStrength256,
771 size_t digest_len_words = kSha3_256DigestWords;
772 return kmac_process_msg_blocks(kKmacOperationSHA3, message, message_len,
773 digest, digest_len_words,
777 status_t kmac_sha3_384(
const uint8_t *message,
size_t message_len,
779 HARDENED_TRY(kmac_init(kKmacOperationSHA3, kKmacSecurityStrength384,
782 size_t digest_len_words = kSha3_384DigestWords;
783 return kmac_process_msg_blocks(kKmacOperationSHA3, message, message_len,
784 digest, digest_len_words,
788 status_t kmac_sha3_512(
const uint8_t *message,
size_t message_len,
790 HARDENED_TRY(kmac_init(kKmacOperationSHA3, kKmacSecurityStrength512,
793 size_t digest_len_words = kSha3_512DigestWords;
794 return kmac_process_msg_blocks(kKmacOperationSHA3, message, message_len,
795 digest, digest_len_words,
799 status_t kmac_shake_128(
const uint8_t *message,
size_t message_len,
800 uint32_t *digest,
size_t digest_len) {
801 HARDENED_TRY(kmac_init(kKmacOperationSHAKE, kKmacSecurityStrength128,
804 return kmac_process_msg_blocks(kKmacOperationSHAKE, message, message_len,
809 status_t kmac_shake_256(
const uint8_t *message,
size_t message_len,
810 uint32_t *digest,
size_t digest_len) {
811 HARDENED_TRY(kmac_init(kKmacOperationSHAKE, kKmacSecurityStrength256,
814 return kmac_process_msg_blocks(kKmacOperationSHAKE, message, message_len,
819 status_t kmac_cshake_128(
const uint8_t *message,
size_t message_len,
820 const unsigned char *func_name,
size_t func_name_len,
821 const unsigned char *cust_str,
size_t cust_str_len,
822 uint32_t *digest,
size_t digest_len) {
823 HARDENED_TRY(kmac_init(kKmacOperationCSHAKE, kKmacSecurityStrength128,
826 HARDENED_TRY(kmac_write_prefix_block(kKmacOperationCSHAKE, func_name,
827 func_name_len, cust_str, cust_str_len));
829 return kmac_process_msg_blocks(kKmacOperationCSHAKE, message, message_len,
834 status_t kmac_cshake_256(
const uint8_t *message,
size_t message_len,
835 const unsigned char *func_name,
size_t func_name_len,
836 const unsigned char *cust_str,
size_t cust_str_len,
837 uint32_t *digest,
size_t digest_len) {
838 HARDENED_TRY(kmac_init(kKmacOperationCSHAKE, kKmacSecurityStrength256,
841 HARDENED_TRY(kmac_write_prefix_block(kKmacOperationCSHAKE, func_name,
842 func_name_len, cust_str, cust_str_len));
844 return kmac_process_msg_blocks(kKmacOperationCSHAKE, message, message_len,
850 const uint8_t *message,
size_t message_len,
851 const unsigned char *cust_str,
size_t cust_str_len,
852 uint32_t *digest,
size_t digest_len) {
854 kmac_init(kKmacOperationKMAC, kKmacSecurityStrength128, key->hw_backed));
857 if (key->share0 != NULL || key->share1 != NULL ||
858 key->len != kKmacSideloadKeyLength / 8) {
859 return OTCRYPTO_BAD_ARGS;
862 if (key->share0 == NULL || key->share1 == NULL) {
863 return OTCRYPTO_BAD_ARGS;
865 HARDENED_TRY(kmac_write_key_block(key));
867 return OTCRYPTO_BAD_ARGS;
870 HARDENED_TRY(kmac_write_prefix_block(kKmacOperationKMAC, NULL,
874 return kmac_process_msg_blocks(kKmacOperationKMAC, message, message_len,
875 digest, digest_len, masked_digest);
879 const uint8_t *message,
size_t message_len,
880 const unsigned char *cust_str,
size_t cust_str_len,
881 uint32_t *digest,
size_t digest_len) {
883 kmac_init(kKmacOperationKMAC, kKmacSecurityStrength256, key->hw_backed));
886 if (key->share0 != NULL || key->share1 != NULL ||
887 key->len != kKmacSideloadKeyLength / 8) {
888 return OTCRYPTO_BAD_ARGS;
891 if (key->share0 == NULL || key->share1 == NULL) {
892 return OTCRYPTO_BAD_ARGS;
894 HARDENED_TRY(kmac_write_key_block(key));
896 return OTCRYPTO_BAD_ARGS;
899 HARDENED_TRY(kmac_write_prefix_block(kKmacOperationKMAC, NULL,
903 return kmac_process_msg_blocks(kKmacOperationKMAC, message, message_len,
904 digest, digest_len, masked_digest);