// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/device/lib/crypto/drivers/kmac.h"

#include "sw/device/lib/base/abs_mmio.h"
#include "sw/device/lib/base/bitfield.h"
#include "sw/device/lib/base/memory.h"

#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
#include "kmac_regs.h"  // Generated.

/**
 * Security strength values.
 *
 * These values corresponds to the half of the capacity of Keccak permutation.
 */
typedef enum kmac_security_str {
  kKmacSecurityStrength128 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128,
  kKmacSecurityStrength224 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L224,
  kKmacSecurityStrength256 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256,
  kKmacSecurityStrength384 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L384,
  kKmacSecurityStrength512 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L512,
} kmac_security_str_t;

/**
 * List of supported KMAC modes.
 *
 * Each `kmac_operation_t` enumeration constant is a bitfield with the
 * following layout:
 * - Bit 0: kmac_en (Whether to enable KMAC datapath).
 * - Bit 1-2: Keccak hashing mode (e.g. SHA, SHAKE, or cSHAKE).
 */
typedef enum kmac_operation {
  kKmacOperationSHA3 = KMAC_CFG_SHADOWED_MODE_VALUE_SHA3 << 1 | 0,
  kKmacOperationSHAKE = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE << 1 | 0,
  kKmacOperationCSHAKE = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE << 1 | 0,
  kKmacOperationKMAC = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE << 1 | 1,
} kmac_operation_t;

/**
 * List of supported KMAC key sizes.
 */
typedef enum kmac_key_length {
  kKmacKeyLength128 = KMAC_KEY_LEN_LEN_VALUE_KEY128,
  kKmacKeyLength192 = KMAC_KEY_LEN_LEN_VALUE_KEY192,
  kKmacKeyLength256 = KMAC_KEY_LEN_LEN_VALUE_KEY256,
  kKmacKeyLength384 = KMAC_KEY_LEN_LEN_VALUE_KEY384,
  kKmacKeyLength512 = KMAC_KEY_LEN_LEN_VALUE_KEY512,
} kmac_key_len_t;

enum {
  kKmacPrefixRegCount = 4 * KMAC_PREFIX_MULTIREG_COUNT,
  kKmacBaseAddr = TOP_EARLGREY_KMAC_BASE_ADDR,
  kKmacCfgAddr = kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET,
  kKmacKeyShare0Addr = kKmacBaseAddr + KMAC_KEY_SHARE0_0_REG_OFFSET,
  kKmacKeyShare1Addr = kKmacBaseAddr + KMAC_KEY_SHARE1_0_REG_OFFSET,
};

// "KMAC" string in little endian
static const crypto_const_uint8_buf_t kKmacFuncNameKMAC = {
    .data = (uint8_t *)"\x4b\x4d\x41\x43",
    .len = 4,
};

// Empty string
static const crypto_const_uint8_buf_t kKmacEmptyString = {
    .data = NULL,
    .len = 0,
};

OT_ASSERT_ENUM_VALUE(kKmacPrefixMaxSize, 4 * KMAC_PREFIX_MULTIREG_COUNT - 4);

static const uint32_t prefix_offsets[] = {
    KMAC_PREFIX_0_REG_OFFSET,  KMAC_PREFIX_1_REG_OFFSET,
    KMAC_PREFIX_2_REG_OFFSET,  KMAC_PREFIX_3_REG_OFFSET,
    KMAC_PREFIX_4_REG_OFFSET,  KMAC_PREFIX_5_REG_OFFSET,
    KMAC_PREFIX_6_REG_OFFSET,  KMAC_PREFIX_7_REG_OFFSET,
    KMAC_PREFIX_8_REG_OFFSET,  KMAC_PREFIX_9_REG_OFFSET,
    KMAC_PREFIX_10_REG_OFFSET,
};

// Check that KEY_SHARE registers form a continuous address space
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_1_REG_OFFSET,
                     KMAC_KEY_SHARE0_0_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_2_REG_OFFSET,
                     KMAC_KEY_SHARE0_1_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_3_REG_OFFSET,
                     KMAC_KEY_SHARE0_2_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_4_REG_OFFSET,
                     KMAC_KEY_SHARE0_3_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_5_REG_OFFSET,
                     KMAC_KEY_SHARE0_4_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_6_REG_OFFSET,
                     KMAC_KEY_SHARE0_5_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_7_REG_OFFSET,
                     KMAC_KEY_SHARE0_6_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_8_REG_OFFSET,
                     KMAC_KEY_SHARE0_7_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_9_REG_OFFSET,
                     KMAC_KEY_SHARE0_8_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_10_REG_OFFSET,
                     KMAC_KEY_SHARE0_9_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_11_REG_OFFSET,
                     KMAC_KEY_SHARE0_10_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_12_REG_OFFSET,
                     KMAC_KEY_SHARE0_11_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_13_REG_OFFSET,
                     KMAC_KEY_SHARE0_12_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_14_REG_OFFSET,
                     KMAC_KEY_SHARE0_13_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_15_REG_OFFSET,
                     KMAC_KEY_SHARE0_14_REG_OFFSET + 4);

OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_1_REG_OFFSET,
                     KMAC_KEY_SHARE1_0_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_2_REG_OFFSET,
                     KMAC_KEY_SHARE1_1_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_3_REG_OFFSET,
                     KMAC_KEY_SHARE1_2_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_4_REG_OFFSET,
                     KMAC_KEY_SHARE1_3_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_5_REG_OFFSET,
                     KMAC_KEY_SHARE1_4_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_6_REG_OFFSET,
                     KMAC_KEY_SHARE1_5_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_7_REG_OFFSET,
                     KMAC_KEY_SHARE1_6_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_8_REG_OFFSET,
                     KMAC_KEY_SHARE1_7_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_9_REG_OFFSET,
                     KMAC_KEY_SHARE1_8_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_10_REG_OFFSET,
                     KMAC_KEY_SHARE1_9_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_11_REG_OFFSET,
                     KMAC_KEY_SHARE1_10_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_12_REG_OFFSET,
                     KMAC_KEY_SHARE1_11_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_13_REG_OFFSET,
                     KMAC_KEY_SHARE1_12_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_14_REG_OFFSET,
                     KMAC_KEY_SHARE1_13_REG_OFFSET + 4);
OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_15_REG_OFFSET,
                     KMAC_KEY_SHARE1_14_REG_OFFSET + 4);

OT_ASSERT_ENUM_VALUE(ARRAYSIZE(prefix_offsets), KMAC_PREFIX_MULTIREG_COUNT);

// Ensure each PREFIX register is 4 bytes
OT_ASSERT_ENUM_VALUE(32, KMAC_PREFIX_PREFIX_FIELD_WIDTH);

/**
 * Return the rate (in bytes) for given security strength.
 *
 * The caller must ensure that `keccak_rate` is not a NULL pointer. This is not
 * checked within this function.
 *
 * @param security_str Security strength.
 * @param keccak_rate The keccak rate in bytes.
 * @return Error code.
 */
OT_WARN_UNUSED_RESULT
static kmac_error_t kmac_get_keccak_rate_bytes(kmac_security_str_t security_str,
                                               size_t *keccak_rate) {
  // Since Keccak state is 1600 bits, rate is calculated with
  // rate = (1600 - 2*x) where x is the security strength (i.e. half the
  // capacity). Here, `keccak_rate` is in bytes.
  switch (security_str) {
    case kKmacSecurityStrength128:
      *keccak_rate = (1600 - 2 * 128) / 8;
      break;
    case kKmacSecurityStrength224:
      *keccak_rate = (1600 - 2 * 224) / 8;
      break;
    case kKmacSecurityStrength256:
      *keccak_rate = (1600 - 2 * 256) / 8;
      break;
    case kKmacSecurityStrength384:
      *keccak_rate = (1600 - 2 * 384) / 8;
      break;
    case kKmacSecurityStrength512:
      *keccak_rate = (1600 - 2 * 512) / 8;
      break;
    default:
      return kKmacArgsError;
  }
  return kKmacOk;
}

/**
 * Return the matching enum of `kmac_key_len_t` for given key length.
 *
 * `key_len_enum` must not be NULL pointer.
 *
 * @param key_len The size of the key in bytes.
 * @param key_len_enum The corresponding enum value to be returned.
 * @return Error code.
 */
OT_WARN_UNUSED_RESULT
static kmac_error_t kmac_get_key_len_bytes(size_t key_len,
                                           kmac_key_len_t *key_len_enum) {
  switch (key_len) {
    case 128 / 8:
      *key_len_enum = kKmacKeyLength128;
      break;
    case 192 / 8:
      *key_len_enum = kKmacKeyLength192;
      break;
    case 256 / 8:
      *key_len_enum = kKmacKeyLength256;
      break;
    case 384 / 8:
      *key_len_enum = kKmacKeyLength384;
      break;
    case 512 / 8:
      *key_len_enum = kKmacKeyLength512;
      break;
    default:
      return kKmacUnsupportedKeySizeError;
  }
  return kKmacOk;
}

bool kmac_is_valid_key_len(size_t key_len) {
  kmac_key_len_t key_len_enum;
  return kmac_get_key_len_bytes(key_len, &key_len_enum) == kKmacOk;
}

kmac_error_t kmac_hwip_default_configure(void) {
  uint32_t status_reg = abs_mmio_read32(kKmacBaseAddr + KMAC_STATUS_REG_OFFSET);

  // Check that core is not in fault state
  if (bitfield_bit32_read(status_reg, KMAC_STATUS_ALERT_FATAL_FAULT_BIT)) {
    return kKmacFatalFaultError;
  }
  if (bitfield_bit32_read(status_reg,
                          KMAC_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_BIT)) {
    return kKmacRecovFaultError;
  }
  // Check that core is not busy
  if (!bitfield_bit32_read(status_reg, KMAC_STATUS_SHA3_IDLE_BIT)) {
    return kKmacNotIdle;
  }

  // Check that there is no err pending in intr state
  uint32_t intr_state =
      abs_mmio_read32(kKmacBaseAddr + KMAC_INTR_STATE_REG_OFFSET);
  if (bitfield_bit32_read(intr_state, KMAC_INTR_STATE_KMAC_ERR_BIT)) {
    return kKmacIntrErrPending;
  }

  // Check CFG.regwen
  uint32_t cfg_regwen =
      abs_mmio_read32(kKmacBaseAddr + KMAC_CFG_REGWEN_REG_OFFSET);
  if (!bitfield_bit32_read(cfg_regwen, KMAC_CFG_REGWEN_EN_BIT)) {
    return kKmacCfgWriteDisabled;
  }

  // Keep err interrupt disabled
  uint32_t intr_reg = KMAC_INTR_ENABLE_REG_RESVAL;
  intr_reg = bitfield_bit32_write(intr_reg, KMAC_INTR_ENABLE_KMAC_ERR_BIT, 0);
  abs_mmio_write32(kKmacBaseAddr + KMAC_INTR_ENABLE_REG_OFFSET, intr_reg);

  // Configure max for entropy period (use UINT32_MAX and let bitfield clamp
  // them to their bitfield)
  uint32_t entropy_period = KMAC_ENTROPY_PERIOD_REG_RESVAL;
  entropy_period = bitfield_field32_write(
      entropy_period, KMAC_ENTROPY_PERIOD_PRESCALER_FIELD, UINT32_MAX);
  entropy_period = bitfield_field32_write(
      entropy_period, KMAC_ENTROPY_PERIOD_WAIT_TIMER_FIELD, UINT32_MAX);
  abs_mmio_write32(kKmacBaseAddr + KMAC_ENTROPY_PERIOD_REG_OFFSET,
                   entropy_period);

  // Configure max for hash threshold (use UINT32_MAX and let bitfield clamp
  // them to their bitfield)
  uint32_t entropy_hash_threshold =
      KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_REG_RESVAL;
  entropy_hash_threshold = bitfield_field32_write(
      entropy_hash_threshold,
      KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_THRESHOLD_FIELD, UINT32_MAX);
  abs_mmio_write32(
      kKmacBaseAddr + KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_REG_OFFSET,
      entropy_hash_threshold);

  // Configure CFG
  uint32_t cfg_reg = KMAC_CFG_SHADOWED_REG_RESVAL;
  // Little_endian
  cfg_reg =
      bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_MSG_ENDIANNESS_BIT, 0);
  cfg_reg =
      bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_STATE_ENDIANNESS_BIT, 0);

  // Sideload: off, default key comes from SW
  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_SIDELOAD_BIT, 0);

  // Entropy mode: EDN
  cfg_reg =
      bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_ENTROPY_MODE_FIELD,
                             KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_EDN_MODE);

  // Use quality randomness for message blocks too
  cfg_reg = bitfield_bit32_write(cfg_reg,
                                 KMAC_CFG_SHADOWED_ENTROPY_FAST_PROCESS_BIT, 1);
  // Do not remask message blocks
  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_MSG_MASK_BIT, 0);

  // Mark entropy source as ready
  cfg_reg =
      bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_ENTROPY_READY_BIT, 1);
  // Err not processed
  cfg_reg =
      bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_ERR_PROCESSED_BIT, 0);
  // Unsupported modes: disabled
  cfg_reg = bitfield_bit32_write(
      cfg_reg, KMAC_CFG_SHADOWED_EN_UNSUPPORTED_MODESTRENGTH_BIT, 0);

  abs_mmio_write32_shadowed(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET,
                            cfg_reg);

  return kKmacOk;
}

/**
 * Wait until given status bit is set.
 *
 * Loops until the `bit_position` of status register reaches the value
 * `bit_value`.
 * @param bit_position The bit position in the status register.
 * @param bit_value Whether it should wait for 0 or 1.
 * @return Error status.
 */
OT_WARN_UNUSED_RESULT
static kmac_error_t wait_status_bit(uint32_t bit_position, bool bit_value) {
  if (bit_position > 31) {
    return kKmacArgsError;
  }

  while (true) {
    uint32_t reg = abs_mmio_read32(kKmacBaseAddr + KMAC_STATUS_REG_OFFSET);
    if (bitfield_bit32_read(reg, KMAC_STATUS_ALERT_FATAL_FAULT_BIT) ||
        bitfield_bit32_read(reg, KMAC_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_BIT)) {
      return kKmacInternalError;
    }
    if (bitfield_bit32_read(reg, bit_position) == bit_value) {
      return kKmacOk;
    }
  }
}

/**
 * Encode a given integer as byte array and return its size along with it.
 *
 * This is a common procedure that can be used to implement both `left_encode`
 * and `right_encode` functions defined in NIST SP 800-185. Given an integer
 * `value` it returns its encoding as a byte array in `encoding_buf`. Meanwhile,
 * `encoding_header` keeps the size of `encoding_buf`. Later the two can be
 * combined as below:
 *
 * left_encode(`value`) = `encoding_header` || `encoding_buf`
 * right_encode(`value`) = `encoding_buf` || `encoding_header`
 *
 * The caller must ensure that `encoding_buf` and `encoding_header` are not
 * NULL pointers. This is not checked within this function.
 *
 * @param value Integer to be encoded.
 * @param encoding_buf The output byte array representing `value`.
 * @param encoding_header The number of bytes written to `encoded_value`.
 * @return Error code.
 */
OT_WARN_UNUSED_RESULT
static kmac_error_t little_endian_encode(size_t value, uint8_t *encoding_buf,
                                         uint8_t *encoding_header) {
  uint8_t len = 0;
  do {
    encoding_buf[len] = value & UINT8_MAX;
    value >>= 8;
    len++;
  } while (value > 0);
  *encoding_header = len;

  return kKmacOk;
}

/**
 * Set prefix registers.
 *
 * This function directly writes to PREFIX registers of KMAC HWIP.
 *
 * @param func_name Function name input in cSHAKE.
 * @param cust_str Customization string input in cSHAKE.
 * @return Error code.
 */
OT_WARN_UNUSED_RESULT
static kmac_error_t kmac_set_prefix_regs(crypto_const_uint8_buf_t func_name,
                                         crypto_const_uint8_buf_t cust_str) {
  // Initialize with 0 so that the last untouched bytes are set as 0x0
  uint32_t prefix_buffer[kKmacPrefixRegCount] = {0x0};
  uint8_t *prefix_buf_ptr = (uint8_t *)prefix_buffer;

  if (func_name.len + cust_str.len > kKmacPrefixMaxSize) {
    return kKmacArgsError;
  }

  size_t func_name_len_bits = 8 * func_name.len;
  size_t cust_str_len_bits = 8 * cust_str.len;
  size_t i = 0;
  size_t write_cnt = 0;
  uint8_t j = 0;
  kmac_error_t err;

  // left_encode(`func_name_len_bits`) below
  err = little_endian_encode(func_name_len_bits, prefix_buf_ptr + 1, &j);
  if (err != kKmacOk) {
    return err;
  }
  prefix_buf_ptr[0] = j;
  write_cnt += j + 1;

  // copy `func_name`
  memcpy(prefix_buf_ptr + write_cnt, func_name.data, func_name.len);

  write_cnt += func_name.len;

  // left_encode(`cust_str_len_bits`) below
  err = little_endian_encode(cust_str_len_bits, prefix_buf_ptr + write_cnt + 1,
                             &j);
  if (err != kKmacOk) {
    return err;
  }

  // copy `cust_str`
  prefix_buf_ptr[write_cnt] = j;
  write_cnt += j + 1;
  memcpy(prefix_buf_ptr + write_cnt, cust_str.data, cust_str.len);

  // Copy from `prefix_buffer` to PREFIX_REGS
  for (i = 0; i < KMAC_PREFIX_MULTIREG_COUNT; i++) {
    abs_mmio_write32(kKmacBaseAddr + prefix_offsets[i], prefix_buffer[i]);
  }

  return kKmacOk;
}

/**
 * Initializes the KMAC configuration.
 *
 * In particular, this function sets the CFG register of KMAC for given
 * `operation_type`. The struct type kmac_operation_t is defined in a way that
 * each field inherently implies a fixed security strength (i.e. half of Keccak
 * capacity). For instance, if we want to run SHA-3 with 224-bit digest size,
 * then `operation_type` = kSHA3_224.
 *
 *
 * @param operation The chosen operation, see kmac_operation_t struct.
 * @return Error code.
 */
OT_WARN_UNUSED_RESULT
static kmac_error_t kmac_init(kmac_operation_t operation,
                              kmac_security_str_t security_str) {
  kmac_error_t err = wait_status_bit(KMAC_STATUS_SHA3_IDLE_BIT, 1);
  if (err != kKmacOk) {
    return err;
  }

  // We need to preserve some bits of CFG register, such as:
  // entropy_mode, entropy_ready etc. On the other hand, some bits
  // need to be reset for each invocation.
  uint32_t cfg_reg =
      abs_mmio_read32(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET);

  // Make sure kmac_en and sideload bits of CFG are reset at each invocation
  // These bits should be set to 1 only if needed by the rest of the code
  // in this function.
  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_KMAC_EN_BIT, 0);
  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_SIDELOAD_BIT, 0);

  // operation bit fields: Bit 0: `kmac_en`, Bit 1-2: `mode`
  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_KMAC_EN_BIT,
                                 operation & 1);
  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_MODE_FIELD,
                                   operation >> 1);

  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_KSTRENGTH_FIELD,
                                   security_str);
  abs_mmio_write32_shadowed(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET,
                            cfg_reg);

  return kKmacOk;
}

/**
 * Configure the prefix registers with customization string.
 *
 * For KMAC, this function ignores `func_name` and uses "KMAC" instead.
 *
 * The caller must ensure that `func_name` and `cust_str` have properly
 * allocated `data` fields whose length matches their `len` fields.
 *
 * In total `func_name` and `cust_str` can be at most `kKmacPrefixMaxSize`
 * bytes.
 *
 * @param operation The KMAC or cSHAKE operation.
 * @param func_name The function name, used for cSHAKE.
 * @param cust_str The customization string (both for cSHAKE and KMAC).
 * @return Error code.
 */
OT_WARN_UNUSED_RESULT
static kmac_error_t kmac_write_prefix_block(kmac_operation_t operation,
                                            crypto_const_uint8_buf_t func_name,
                                            crypto_const_uint8_buf_t cust_str) {
  if (operation == kKmacOperationCSHAKE) {
    return kmac_set_prefix_regs(func_name, cust_str);
  } else if (operation == kKmacOperationKMAC) {
    return kmac_set_prefix_regs(/*func_name=*/kKmacFuncNameKMAC, cust_str);
  }
  return kKmacArgsError;
}

/**
 * Update the key registers with given key shares.
 *
 * The caller must ensure that `key` struct is properly populated (no NULL
 * pointers and matching `len`).
 *
 * The accepted `key->len` values are {128 / 8, 192 / 8, 256 / 8, 384 / 8,
 * 512 / 8}, otherwise an error will be returned.
 *
 * @param key The input key passed as a struct.
 * @return Error code.
 */
OT_WARN_UNUSED_RESULT
static kmac_error_t kmac_write_key_block(kmac_blinded_key_t *key) {
  kmac_key_len_t key_len_enum;
  kmac_error_t err = kmac_get_key_len_bytes(key->len, &key_len_enum);
  if (err != kKmacOk) {
    return err;
  }

  uint32_t key_len_reg = bitfield_field32_write(
      KMAC_KEY_LEN_REG_RESVAL, KMAC_KEY_LEN_LEN_FIELD, key_len_enum);
  abs_mmio_write32(kKmacBaseAddr + KMAC_KEY_LEN_REG_OFFSET, key_len_reg);

  for (size_t i = 0; i < key->len; i += 4) {
    abs_mmio_write32(kKmacKeyShare0Addr + i, key->share0[i / 4]);
    abs_mmio_write32(kKmacKeyShare1Addr + i, key->share1[i / 4]);
  }

  return kKmacOk;
}

/**
 * Common routine for feeding message blocks during SHA/SHAKE/cSHAKE/KMAC.
 *
 * Before running this, the operation type must be configured with kmac_init.
 * Then, we can use this function to feed various bytes of data to the KMAC
 * core. Note that this is a one-shot implementation, and it does not support
 * streaming mode. This decision is in accord with OpenTitan's Crypto Library
 * Specification. Refer to the Hash section of this specification.
 *
 * Current implementation has few limitiations:
 *
 * 1. `message.data` pointer is assumed to be word-aligned. The case where
 * `data` field is not divisible by 4 is not yet implemented. This is about
 * extra protection against SCA.
 *
 * 2. Currently, there is no error check on consisteny of the input parameters.
 * For instance, one can invoke SHA-3_224 with digest_len=32, which will produce
 * 256 bits of digest.
 *
 * The caller must ensure that `message` and `digest` have properly
 * allocated `data` fields whose length matches their `len` fields.
 *
 * @param operation The operation type.
 * @param message Input message string.
 * @param digest The struct to which the result will be written.
 * @return Error code.
 */
OT_WARN_UNUSED_RESULT
static kmac_error_t kmac_process_msg_blocks(kmac_operation_t operation,
                                            crypto_const_uint8_buf_t message,
                                            crypto_uint8_buf_t *digest) {
  uint32_t cmd_reg = KMAC_CMD_REG_RESVAL;
  kmac_error_t err;

  // Assumption(1): `message.len` > 0 and `digest->len` > 0
  // Assumption(2): message.data % 4 = 0, i.e. the message.data is 32-bit
  // aligned

  err = wait_status_bit(KMAC_STATUS_SHA3_IDLE_BIT, 1);
  // Issue the start command, so that messages written to MSG_FIFO are forwarded
  // to Keccak
  cmd_reg = bitfield_field32_write(cmd_reg, KMAC_CMD_CMD_FIELD,
                                   KMAC_CMD_CMD_VALUE_START);
  abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);
  err = wait_status_bit(KMAC_STATUS_SHA3_ABSORB_BIT, 1);
  if (err != kKmacOk) {
    return err;
  }

  // Begin by writing a word at a time
  uint32_t *word_ptr = (uint32_t *)message.data;
  size_t i = 0;
  for (; i < message.len / 4; i++) {
    err = wait_status_bit(KMAC_STATUS_FIFO_FULL_BIT, 0);
    if (err != kKmacOk) {
      return err;
    }
    abs_mmio_write32(kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET, word_ptr[i]);
  }

  // For the last few bytes, we need to write byte at a time
  // i = 4*(message.len/4)
  for (i = 4 * i; i < message.len; i++) {
    err = wait_status_bit(KMAC_STATUS_FIFO_FULL_BIT, 0);
    if (err != kKmacOk) {
      return err;
    }
    abs_mmio_write8(kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET + (i % 4),
                    message.data[i]);
  }

  // If operation=KMAC, then we need to write `right_encode(digest->len)`
  if (operation == kKmacOperationKMAC) {
    uint32_t digest_len_bits = 8 * digest->len;
    if (digest_len_bits / 8 != digest->len) {
      return kKmacDigestLenTooLongError;
    }

    // right_encode(`digest_len_bit`) below
    // The encoded buffer in total occupies at most 256 bytes according to
    // NIST SP 800-185 (1 byte for encoding header and 255 byte for the encoded
    // buffer at max)
    uint8_t buf[256] = {0};
    uint8_t encoding_header;
    err = little_endian_encode(digest_len_bits, buf, &encoding_header);
    if (err != kKmacOk) {
      return err;
    }
    buf[encoding_header] = encoding_header;

    // Because the MSG_FIFO is also little endian we need to write in reverse
    // order
    for (size_t i = 0; i < encoding_header; i++) {
      abs_mmio_write8(
          kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET + ((message.len + i) % 4),
          buf[encoding_header - i - 1]);
    }

    // Finally write `encoding_header` as the last byte
    abs_mmio_write8(
        kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET + ((message.len + i) % 4),
        buf[encoding_header]);
  }

  // Issue the process command, so that squeezing phase can start
  cmd_reg = KMAC_CMD_REG_RESVAL;
  cmd_reg = bitfield_field32_write(cmd_reg, KMAC_CMD_CMD_FIELD,
                                   KMAC_CMD_CMD_VALUE_PROCESS);
  abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);

  // Wait until squeezing is done
  err = wait_status_bit(KMAC_STATUS_SHA3_SQUEEZE_BIT, 1);
  if (err != kKmacOk) {
    return err;
  }

  uint32_t cfg_reg =
      abs_mmio_read32(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET);
  uint32_t keccak_str =
      bitfield_field32_read(cfg_reg, KMAC_CFG_SHADOWED_KSTRENGTH_FIELD);
  size_t keccak_rate;
  err = kmac_get_keccak_rate_bytes(keccak_str, &keccak_rate);
  if (err != kKmacOk) {
    return err;
  }

  // Finally, we can read the two shares of digest and XOR them
  // Here the counter i denotes the number of bytes read from Keccak state
  for (i = 0; i < digest->len; i++) {
    // Do we require additional Keccak rounds?
    if ((i % keccak_rate) == 0 && i > 0) {
      // if we consumed all Keccak state and aren't done yet, run one more
      // Keccak round
      cmd_reg = KMAC_CMD_REG_RESVAL;
      cmd_reg = bitfield_field32_write(cmd_reg, KMAC_CMD_CMD_FIELD,
                                       KMAC_CMD_CMD_VALUE_RUN);
      abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);

      // Let Keccak core finish the extra squeezing round
      err = wait_status_bit(KMAC_STATUS_SHA3_SQUEEZE_BIT, 1);
      if (err != kKmacOk) {
        return err;
      }
    }
    digest->data[i] = abs_mmio_read8(kKmacBaseAddr + KMAC_STATE_REG_OFFSET +
                                     (i % keccak_rate));
    digest->data[i] ^=
        abs_mmio_read8(kKmacBaseAddr + KMAC_STATE_REG_OFFSET +
                       KMAC_STATE_SIZE_BYTES / 2 + (i % keccak_rate));
  }

  // Release the KMAC core, so that it goes back to idle mode
  cmd_reg = KMAC_CMD_REG_RESVAL;
  cmd_reg = bitfield_field32_write(cmd_reg, KMAC_CMD_CMD_FIELD,
                                   KMAC_CMD_CMD_VALUE_DONE);
  abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);

  return kKmacOk;
}

OT_WARN_UNUSED_RESULT
kmac_error_t kmac_sha3_224(crypto_const_uint8_buf_t message,
                           crypto_uint8_buf_t *digest) {
  kmac_error_t err = kmac_init(kKmacOperationSHA3, kKmacSecurityStrength224);
  if (err != kKmacOk) {
    return err;
  }

  return kmac_process_msg_blocks(kKmacOperationSHA3, message, digest);
}

OT_WARN_UNUSED_RESULT
kmac_error_t kmac_sha3_256(crypto_const_uint8_buf_t message,
                           crypto_uint8_buf_t *digest) {
  kmac_error_t err = kmac_init(kKmacOperationSHA3, kKmacSecurityStrength256);
  if (err != kKmacOk) {
    return err;
  }

  return kmac_process_msg_blocks(kKmacOperationSHA3, message, digest);
}

OT_WARN_UNUSED_RESULT
kmac_error_t kmac_sha3_384(crypto_const_uint8_buf_t message,
                           crypto_uint8_buf_t *digest) {
  kmac_error_t err = kmac_init(kKmacOperationSHA3, kKmacSecurityStrength384);

  if (err != kKmacOk) {
    return err;
  }

  return kmac_process_msg_blocks(kKmacOperationSHA3, message, digest);
}

OT_WARN_UNUSED_RESULT
kmac_error_t kmac_sha3_512(crypto_const_uint8_buf_t message,
                           crypto_uint8_buf_t *digest) {
  kmac_error_t err = kmac_init(kKmacOperationSHA3, kKmacSecurityStrength512);
  if (err != kKmacOk) {
    return err;
  }

  return kmac_process_msg_blocks(kKmacOperationSHA3, message, digest);
}

OT_WARN_UNUSED_RESULT
kmac_error_t kmac_shake_128(crypto_const_uint8_buf_t message,
                            crypto_uint8_buf_t *digest) {
  kmac_error_t err = kmac_init(kKmacOperationSHAKE, kKmacSecurityStrength128);
  if (err != kKmacOk) {
    return err;
  }

  return kmac_process_msg_blocks(kKmacOperationSHAKE, message, digest);
}

OT_WARN_UNUSED_RESULT
kmac_error_t kmac_shake_256(crypto_const_uint8_buf_t message,
                            crypto_uint8_buf_t *digest) {
  kmac_error_t err = kmac_init(kKmacOperationSHAKE, kKmacSecurityStrength256);
  if (err != kKmacOk) {
    return err;
  }

  return kmac_process_msg_blocks(kKmacOperationSHAKE, message, digest);
}

OT_WARN_UNUSED_RESULT
kmac_error_t kmac_cshake_128(crypto_const_uint8_buf_t message,
                             crypto_const_uint8_buf_t func_name,
                             crypto_const_uint8_buf_t cust_str,
                             crypto_uint8_buf_t *digest) {
  kmac_error_t err = kmac_init(kKmacOperationCSHAKE, kKmacSecurityStrength128);
  if (err != kKmacOk) {
    return err;
  }

  err = kmac_write_prefix_block(kKmacOperationCSHAKE, func_name, cust_str);
  if (err != kKmacOk) {
    return err;
  }

  return kmac_process_msg_blocks(kKmacOperationCSHAKE, message, digest);
}

OT_WARN_UNUSED_RESULT
kmac_error_t kmac_cshake_256(crypto_const_uint8_buf_t message,
                             crypto_const_uint8_buf_t func_name,
                             crypto_const_uint8_buf_t cust_str,
                             crypto_uint8_buf_t *digest) {
  kmac_error_t err = kmac_init(kKmacOperationCSHAKE, kKmacSecurityStrength256);
  if (err != kKmacOk) {
    return err;
  }

  err = kmac_write_prefix_block(kKmacOperationCSHAKE, func_name, cust_str);
  if (err != kKmacOk) {
    return err;
  }

  return kmac_process_msg_blocks(kKmacOperationCSHAKE, message, digest);
}

OT_WARN_UNUSED_RESULT
kmac_error_t kmac_kmac_128(kmac_blinded_key_t *key,
                           crypto_const_uint8_buf_t message,
                           crypto_const_uint8_buf_t cust_str,
                           crypto_uint8_buf_t *digest) {
  kmac_error_t err = kmac_init(kKmacOperationKMAC, kKmacSecurityStrength128);
  if (err != kKmacOk) {
    return err;
  }

  err = kmac_write_key_block(key);
  if (err != kKmacOk) {
    return err;
  }

  err = kmac_write_prefix_block(kKmacOperationKMAC, kKmacEmptyString, cust_str);
  if (err != kKmacOk) {
    return err;
  }

  return kmac_process_msg_blocks(kKmacOperationKMAC, message, digest);
}

OT_WARN_UNUSED_RESULT
kmac_error_t kmac_kmac_256(kmac_blinded_key_t *key,
                           crypto_const_uint8_buf_t message,
                           crypto_const_uint8_buf_t cust_str,
                           crypto_uint8_buf_t *digest) {
  kmac_error_t err = kmac_init(kKmacOperationKMAC, kKmacSecurityStrength256);
  if (err != kKmacOk) {
    return err;
  }

  err = kmac_write_key_block(key);
  if (err != kKmacOk) {
    return err;
  }

  err = kmac_write_prefix_block(kKmacOperationKMAC, kKmacEmptyString, cust_str);
  if (err != kKmacOk) {
    return err;
  }

  return kmac_process_msg_blocks(kKmacOperationKMAC, message, digest);
}
