// 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/dif/dif_hmac.h"

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

#include "hmac_regs.h"  // Generated.

/**
 * Read the status register from `hmac`.
 *
 * @param hmac The HMAC device to read the status register from.
 * @return The contents of hmac.STATUS.
 */
static uint32_t get_status(const dif_hmac_t *hmac) {
  return mmio_region_read32(hmac->base_addr, HMAC_STATUS_REG_OFFSET);
}

/**
 * Returns the number of entries in the FIFO of `hmac`. If the FIFO is empty,
 * this function will return 0, and if the FIFO is full, this funciton will
 * return `HMAC_FIFO_MAX`.
 *
 * @param hmac The HMAC device to check the FIFO size of.
 * @return The number of entries in the HMAC FIFO.
 */
static uint32_t get_fifo_entry_count(const dif_hmac_t *hmac) {
  return bitfield_field32_read(get_status(hmac),
                               (bitfield_field32_t){
                                   .mask = HMAC_STATUS_FIFO_DEPTH_MASK,
                                   .index = HMAC_STATUS_FIFO_DEPTH_OFFSET,
                               });
}

/**
 * A helper function for calculating `HMAC_FIFO_MAX` - `get_fifo_entry_count()`.
 */
static uint32_t get_fifo_available_space(const dif_hmac_t *hmac) {
  return HMAC_MSG_FIFO_SIZE_WORDS - get_fifo_entry_count(hmac);
}

/**
 * Convert from a `dif_hmac_interrupt_t` to the appropriate bit index.
 * INTR_STATE, INTR_ENABLE, and INTR_TEST registers have the same bit offset.
 */
static bool irq_bit_offset_get(dif_hmac_interrupt_t irq_type,
                               uint8_t *offset_out) {
  ptrdiff_t offset;
  switch (irq_type) {
    case kDifHmacInterruptHmacDone:
      offset = HMAC_INTR_COMMON_HMAC_DONE;
      break;
    case kDifHmacInterruptFifoEmpty:
      offset = HMAC_INTR_COMMON_FIFO_EMPTY;
      break;
    case kDifHmacInterruptHmacErr:
      offset = HMAC_INTR_COMMON_HMAC_ERR;
      break;
    default:
      return false;
  }

  *offset_out = offset;

  return true;
}

dif_hmac_result_t dif_hmac_init(const dif_hmac_config_t *config,
                                dif_hmac_t *hmac) {
  // Basic sanity checks on parameters. In `kDifHmacModeHmac` mode a key is
  // required.
  if (config == NULL || hmac == NULL) {
    return kDifHmacBadArg;
  }

  hmac->base_addr = config->base_addr;

  // Clear the config, stopping the SHA engine.
  mmio_region_write32(config->base_addr, HMAC_CFG_REG_OFFSET, 0);

  // Clear INTER.
  mmio_region_write32(config->base_addr, HMAC_INTR_STATE_REG_OFFSET,
                      (1 << HMAC_INTR_STATE_HMAC_DONE) |
                          (1 << HMAC_INTR_STATE_FIFO_EMPTY) |
                          (1 << HMAC_INTR_STATE_HMAC_ERR));

  uint32_t device_config = 0;

  // Set the byte-order of the input message.
  switch (config->message_endianness) {
    case kDifHmacEndiannessBig:
      device_config |= (1 << HMAC_CFG_ENDIAN_SWAP);
      break;
    case kDifHmacEndiannessLittle:
      break;
    default:
      return kDifHmacError;
  }

  // Set the byte-order of the digest.
  switch (config->digest_endianness) {
    case kDifHmacEndiannessBig:
      device_config |= (1 << HMAC_CFG_DIGEST_SWAP);
      break;
    case kDifHmacEndiannessLittle:
      break;
    default:
      return kDifHmacError;
  }

  // Write the configuration.
  mmio_region_write32(config->base_addr, HMAC_CFG_REG_OFFSET, device_config);

  return kDifHmacOk;
}

dif_hmac_result_t dif_hmac_irq_state_get(const dif_hmac_t *hmac,
                                         dif_hmac_interrupt_t irq_type,
                                         dif_hmac_enable_t *state) {
  if (hmac == NULL || state == NULL) {
    return kDifHmacBadArg;
  }

  uint8_t offset;
  if (!irq_bit_offset_get(irq_type, &offset)) {
    return kDifHmacError;
  }

  // Get the interrupt state.
  bool enabled = mmio_region_get_bit32(hmac->base_addr,
                                       HMAC_INTR_STATE_REG_OFFSET, offset);
  *state = (enabled ? kDifHmacEnable : kDifHmacDisable);

  return kDifHmacOk;
}

dif_hmac_result_t dif_hmac_irq_state_clear(const dif_hmac_t *hmac,
                                           dif_hmac_interrupt_t irq_type) {
  if (hmac == NULL) {
    return kDifHmacBadArg;
  }

  uint8_t offset;
  if (!irq_bit_offset_get(irq_type, &offset)) {
    return kDifHmacError;
  }

  // Clear the interrupt state.
  mmio_region_write_only_set_bit32(hmac->base_addr, HMAC_INTR_STATE_REG_OFFSET,
                                   offset);

  return kDifHmacOk;
}

dif_hmac_result_t dif_hmac_irqs_disable(const dif_hmac_t *hmac,
                                        uint32_t *state) {
  if (hmac == NULL) {
    return kDifHmacBadArg;
  }

  // Pass the interrupt state back to the caller.
  if (state != NULL) {
    *state = mmio_region_read32(hmac->base_addr, HMAC_INTR_ENABLE_REG_OFFSET);
  }

  // Disable all interrupts.
  mmio_region_write32(hmac->base_addr, HMAC_INTR_ENABLE_REG_OFFSET, 0u);

  return kDifHmacOk;
}

dif_hmac_result_t dif_hmac_irqs_restore(const dif_hmac_t *hmac,
                                        uint32_t state) {
  if (hmac == NULL) {
    return kDifHmacBadArg;
  }

  // Restore interrupt state.
  mmio_region_write32(hmac->base_addr, HMAC_INTR_ENABLE_REG_OFFSET, state);

  return kDifHmacOk;
}

dif_hmac_result_t dif_hmac_irq_control(const dif_hmac_t *hmac,
                                       dif_hmac_interrupt_t irq_type,
                                       dif_hmac_enable_t enable) {
  if (hmac == NULL) {
    return kDifHmacBadArg;
  }

  uint8_t offset;
  if (!irq_bit_offset_get(irq_type, &offset)) {
    return kDifHmacError;
  }

  // Enable/Disable interrupt.
  if (enable == kDifHmacEnable) {
    mmio_region_nonatomic_set_bit32(hmac->base_addr,
                                    HMAC_INTR_ENABLE_REG_OFFSET, offset);
  } else {
    mmio_region_nonatomic_clear_bit32(hmac->base_addr,
                                      HMAC_INTR_ENABLE_REG_OFFSET, offset);
  }

  return kDifHmacOk;
}

dif_hmac_result_t dif_hmac_irq_force(const dif_hmac_t *hmac,
                                     dif_hmac_interrupt_t irq_type) {
  if (hmac == NULL) {
    return kDifHmacBadArg;
  }

  uint8_t offset;
  if (!irq_bit_offset_get(irq_type, &offset)) {
    return kDifHmacError;
  }

  // Force the requested interrupt.
  mmio_region_nonatomic_set_bit32(hmac->base_addr, HMAC_INTR_TEST_REG_OFFSET,
                                  offset);

  return kDifHmacOk;
}

dif_hmac_result_t dif_hmac_mode_hmac_start(const dif_hmac_t *hmac,
                                           const uint8_t *key) {
  if (hmac == NULL || key == NULL) {
    return kDifHmacBadArg;
  }

  // Disable SHA256 while configuring and to clear the digest.
  mmio_region_nonatomic_clear_bit32(hmac->base_addr, HMAC_CFG_REG_OFFSET,
                                    HMAC_CFG_SHA_EN);

  // Set the HMAC key.
  // TODO Static assert register layout.
  mmio_region_memcpy_to_mmio32(hmac->base_addr, HMAC_KEY_0_REG_OFFSET, key,
                               HMAC_PARAM_NUMWORDS * sizeof(uint32_t));

  // Set HMAC to process in HMAC mode (not SHA256-only mode).
  mmio_region_nonatomic_set_mask32(
      hmac->base_addr, HMAC_CFG_REG_OFFSET,
      (1 << HMAC_CFG_SHA_EN) | (1 << HMAC_CFG_HMAC_EN), 0);

  // Begin HMAC operation.
  mmio_region_nonatomic_set_bit32(hmac->base_addr, HMAC_CMD_REG_OFFSET,
                                  HMAC_CMD_HASH_START);
  return kDifHmacOk;
}

dif_hmac_result_t dif_hmac_mode_sha256_start(const dif_hmac_t *hmac) {
  if (hmac == NULL) {
    return kDifHmacBadArg;
  }

  // Disable SHA256 while configuring and to clear the digest.
  mmio_region_nonatomic_clear_bit32(hmac->base_addr, HMAC_CFG_REG_OFFSET,
                                    HMAC_CFG_SHA_EN);

  // Disable HMAC mode.
  mmio_region_nonatomic_clear_bit32(hmac->base_addr, HMAC_CFG_REG_OFFSET,
                                    HMAC_CFG_HMAC_EN);

  // Set HMAC to process in SHA256-only mode.
  mmio_region_nonatomic_set_bit32(hmac->base_addr, HMAC_CFG_REG_OFFSET,
                                  HMAC_CFG_SHA_EN);

  // Begin SHA256-only operation.
  mmio_region_nonatomic_set_bit32(hmac->base_addr, HMAC_CMD_REG_OFFSET,
                                  HMAC_CMD_HASH_START);

  return kDifHmacOk;
}

dif_hmac_fifo_result_t dif_hmac_fifo_push(const dif_hmac_t *hmac,
                                          const void *data, size_t len,
                                          size_t *bytes_sent) {
  if (hmac == NULL || data == NULL) {
    return kDifHmacFifoBadArg;
  }

  const uint8_t *data_sent = (const uint8_t *)data;
  size_t bytes_remaining = len;

  while (bytes_remaining > 0 && get_fifo_available_space(hmac) > 0) {
    bool word_aligned = (uintptr_t)data_sent % sizeof(uint32_t) == 0;
    size_t bytes_written = 0;

    if (bytes_remaining < sizeof(uint32_t) || !word_aligned) {
      // Individual byte writes are needed if the buffer isn't aligned or there
      // are no more full words to write.
      mmio_region_write8(hmac->base_addr, HMAC_MSG_FIFO_REG_OFFSET, *data_sent);
      bytes_written = 1;
    } else {
      // `data_sent` is word-aligned and there are still words to write.
      uint32_t word = read_32(data_sent);
      mmio_region_write32(hmac->base_addr, HMAC_MSG_FIFO_REG_OFFSET, word);
      bytes_written = sizeof(uint32_t);
    }

    bytes_remaining -= bytes_written;
    data_sent += bytes_written;
  }

  if (bytes_sent != NULL) {
    *bytes_sent = len - bytes_remaining;
  }

  if (bytes_remaining > 0) {
    return kDifHmacFifoFull;
  }

  return kDifHmacFifoOk;
}

dif_hmac_result_t dif_hmac_fifo_count_entries(const dif_hmac_t *hmac,
                                              uint32_t *num_entries) {
  if (hmac == NULL || num_entries == NULL) {
    return kDifHmacBadArg;
  }

  *num_entries = get_fifo_entry_count(hmac);

  return kDifHmacOk;
}

dif_hmac_result_t dif_hmac_get_message_length(const dif_hmac_t *hmac,
                                              uint64_t *msg_len) {
  if (hmac == NULL || msg_len == NULL) {
    return kDifHmacBadArg;
  }

  uint64_t msg_lower =
      mmio_region_read32(hmac->base_addr, HMAC_MSG_LENGTH_LOWER_REG_OFFSET);
  uint64_t msg_upper =
      mmio_region_read32(hmac->base_addr, HMAC_MSG_LENGTH_UPPER_REG_OFFSET);

  *msg_len = (msg_upper << 32) | msg_lower;

  return kDifHmacOk;
}

dif_hmac_result_t dif_hmac_process(const dif_hmac_t *hmac) {
  if (hmac == NULL) {
    return kDifHmacBadArg;
  }

  mmio_region_nonatomic_set_bit32(hmac->base_addr, HMAC_CMD_REG_OFFSET,
                                  HMAC_CMD_HASH_PROCESS);
  return kDifHmacOk;
}

dif_hmac_digest_result_t dif_hmac_digest_read(const dif_hmac_t *hmac,
                                              dif_hmac_digest_t *digest) {
  if (hmac == NULL || digest == NULL) {
    return kDifHmacDigestBadArg;
  }

  // Check if hmac_done is asserted.
  bool done = mmio_region_get_bit32(hmac->base_addr, HMAC_INTR_STATE_REG_OFFSET,
                                    HMAC_INTR_STATE_HMAC_DONE);

  if (done) {
    // Clear hmac_done.
    mmio_region_nonatomic_set_bit32(hmac->base_addr, HMAC_INTR_STATE_REG_OFFSET,
                                    HMAC_INTR_STATE_HMAC_DONE);
  } else {
    return kDifHmacDigestProcessing;
  }

  // Read the digest.
  // TODO Static assert register layout.
  mmio_region_memcpy_from_mmio32(hmac->base_addr, HMAC_DIGEST_0_REG_OFFSET,
                                 digest->digest,
                                 HMAC_PARAM_NUMWORDS * sizeof(uint32_t));

  return kDifHmacDigestOk;
}

dif_hmac_result_t dif_hmac_wipe_secret(const dif_hmac_t *hmac,
                                       uint32_t entropy) {
  if (hmac == NULL) {
    return kDifHmacBadArg;
  }

  mmio_region_write32(hmac->base_addr, HMAC_WIPE_SECRET_REG_OFFSET, entropy);

  return kDifHmacOk;
}
