5 #include "sw/device/silicon_creator/lib/drivers/kmac.h"
10 #include "sw/device/silicon_creator/lib/error.h"
13 #include "kmac_regs.h"
25 kShake256KeccakCapacity = 2 * 256,
31 kShake256KeccakRateBits = 1600 - kShake256KeccakCapacity,
35 kShake256KeccakRateBytes = kShake256KeccakRateBits / 8,
39 kShake256KeccakRateWords = kShake256KeccakRateBytes /
sizeof(uint32_t),
43 kStateShareSize = KMAC_STATE_SIZE_BYTES / 2,
47 kAddrStateShare0 = kBase + KMAC_STATE_REG_OFFSET,
51 kAddrStateShare1 = kBase + KMAC_STATE_REG_OFFSET + kStateShareSize,
55 static_assert(kShake256KeccakRateWords <= kStateShareSize,
56 "assert SHAKE256 rate is <= share size");
58 static const uint32_t kEntropySeed[] = {0x5d2a3764, 0x37d3ecba, 0xe1859094,
59 0xb153e3fe, 0x09596819, 0x3e85a6e8,
60 0xb6dcdaba, 0x50dc409c, 0x11e1ebd1};
113 rom_error_t res = launder32(kErrorOk ^ UINT32_MAX);
117 uint32_t intr_state = abs_mmio_read32(kBase + KMAC_INTR_STATE_REG_OFFSET);
119 intr_state, KMAC_INTR_STATE_KMAC_ERR_BIT));
123 is_error ^= (~err_bit) + 1;
126 status = abs_mmio_read32(kBase + KMAC_STATUS_REG_OFFSET);
131 res ^= ((~flag) + 1) << 1;
145 return kErrorKmacInvalidStatus;
156 HARDENED_RETURN_IF_ERROR(poll_state(KMAC_STATUS_SHA3_IDLE_BIT));
158 uint32_t entropy_period_reg = KMAC_ENTROPY_PERIOD_REG_RESVAL;
161 entropy_period_reg, KMAC_ENTROPY_PERIOD_WAIT_TIMER_FIELD,
162 KMAC_ENTROPY_PERIOD_WAIT_TIMER_MASK);
165 entropy_period_reg, KMAC_ENTROPY_PERIOD_PRESCALER_FIELD,
166 KMAC_ENTROPY_PERIOD_PRESCALER_MASK);
167 abs_mmio_write32(kBase + KMAC_ENTROPY_PERIOD_REG_OFFSET, entropy_period_reg);
169 uint32_t cfg_reg = KMAC_CFG_SHADOWED_REG_RESVAL;
178 KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256);
197 KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_SW_MODE);
213 cfg_reg, KMAC_CFG_SHADOWED_EN_UNSUPPORTED_MODESTRENGTH_BIT, 0);
214 abs_mmio_write32_shadowed(kBase + KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
219 abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[0]);
220 abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[1]);
221 abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[2]);
222 abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[3]);
223 abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[4]);
224 abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[5]);
225 abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[6]);
226 abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[7]);
227 abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[8]);
237 static void issue_command(uint32_t cmd_value) {
239 abs_mmio_write32(kBase + KMAC_CMD_REG_OFFSET, cmd_reg);
242 rom_error_t kmac_keymgr_configure(
void) {
244 .entropy_fast_process =
false,
248 .mode = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE,
252 rom_error_t kmac_kmac256_sw_configure(
void) {
253 kmac_kmac256_set_prefix(NULL, 0);
255 .entropy_fast_process =
false,
259 .mode = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE,
263 rom_error_t kmac_kmac256_hw_configure(
void) {
264 kmac_kmac256_set_prefix(NULL, 0);
266 .entropy_fast_process =
false,
270 .mode = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE,
274 rom_error_t kmac_shake256_configure(
void) {
276 .entropy_fast_process =
false,
280 .mode = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE,
284 rom_error_t kmac_shake256_start(
void) {
286 HARDENED_RETURN_IF_ERROR(poll_state(KMAC_STATUS_SHA3_IDLE_BIT));
289 issue_command(KMAC_CMD_CMD_VALUE_START);
295 HARDENED_RETURN_IF_ERROR(poll_state(KMAC_STATUS_SHA3_ABSORB_BIT));
300 void kmac_shake256_absorb(
const uint8_t *in,
size_t inlen) {
314 abs_mmio_write8(kBase + KMAC_MSG_FIFO_REG_OFFSET, *in);
318 for (; inlen >=
sizeof(uint32_t);
319 inlen -=
sizeof(uint32_t), in +=
sizeof(uint32_t)) {
320 abs_mmio_write32(kBase + KMAC_MSG_FIFO_REG_OFFSET,
read_32(in));
324 for (; inlen > 0; --inlen, ++in) {
325 abs_mmio_write8(kBase + KMAC_MSG_FIFO_REG_OFFSET, *in);
330 void kmac_shake256_absorb_words(
const uint32_t *in,
size_t inlen) {
341 for (; inlen > 0; --inlen, ++in) {
342 abs_mmio_write32(kBase + KMAC_MSG_FIFO_REG_OFFSET, *in);
347 void kmac_shake256_squeeze_start(
void) {
349 issue_command(KMAC_CMD_CMD_VALUE_PROCESS);
352 rom_error_t kmac_shake256_squeeze_end(uint32_t *out,
size_t outlen) {
354 while (launder32(idx) < outlen) {
360 HARDENED_RETURN_IF_ERROR(poll_state(KMAC_STATUS_SHA3_SQUEEZE_BIT));
365 for (; launder32(idx) < outlen && offset < kShake256KeccakRateWords;
368 abs_mmio_read32(kAddrStateShare0 + offset *
sizeof(uint32_t));
370 abs_mmio_read32(kAddrStateShare1 + offset *
sizeof(uint32_t));
371 out[idx] = share0 ^ share1;
375 if (offset == kShake256KeccakRateWords) {
379 issue_command(KMAC_CMD_CMD_VALUE_RUN);
385 HARDENED_RETURN_IF_ERROR(poll_state(KMAC_STATUS_SHA3_SQUEEZE_BIT));
388 issue_command(KMAC_CMD_CMD_VALUE_DONE);
393 #define WORD_BITS (sizeof(uint32_t) * 8)
394 #define KEY_CASE(x_) \
395 case x_ / WORD_BITS: \
396 klen = KMAC_KEY_LEN_LEN_VALUE_KEY##x_; \
398 rom_error_t kmac_kmac256_sw_key(
const uint32_t *key,
size_t len) {
407 return kErrorKmacInvalidKeySize;
409 abs_mmio_write32(kBase + KMAC_KEY_LEN_REG_OFFSET, klen);
410 for (
size_t i = 0; i < KMAC_KEY_SHARE0_MULTIREG_COUNT; ++i) {
411 uint32_t value = i < len ? key[i] : 0;
413 kBase + KMAC_KEY_SHARE0_0_REG_OFFSET + i *
sizeof(uint32_t), value);
415 kBase + KMAC_KEY_SHARE1_0_REG_OFFSET + i *
sizeof(uint32_t), 0);
420 void kmac_kmac256_set_prefix(
const void *prefix,
size_t len) {
423 HARDENED_CHECK_LT(len, 32);
424 uint32_t regs[KMAC_PREFIX_MULTIREG_COUNT] = {
428 char *r = (
char *)®s[2];
433 r[-1] = (char)(len * 8);
436 for (
size_t i = 0; i < KMAC_PREFIX_MULTIREG_COUNT; ++i) {
437 abs_mmio_write32(kBase + KMAC_PREFIX_0_REG_OFFSET + i *
sizeof(uint32_t),
442 rom_error_t kmac_kmac256_final(uint32_t *result,
size_t rlen) {
445 uint8_t buffer[
sizeof(size_t) + 1];
446 size_t val = rlen * 32;
448 size_t p =
sizeof(buffer) - 1;
450 buffer[--p] = val & 0xFF;
454 buffer[
sizeof(buffer) - 1] = (uint8_t)n;
455 kmac_shake256_absorb(buffer + p, n + 1);
458 kmac_shake256_squeeze_start();
459 return kmac_shake256_squeeze_end(result, rlen);
463 extern rom_error_t kmac_kmac256_start(
void);
464 extern void kmac_kmac256_absorb(
const void *data,
size_t len);