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

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

#include "csrng_regs.h"  // Generated

enum {
  /**
   * CSRNG genbits buffer size in uint32_t words.
   */
  kCsrngGenBitsBufferSize = 4,
};

/**
 * Supported CSRNG application commands.
 * See https://docs.opentitan.org/hw/ip/csrng/doc/#command-header for
 * details.
 */
typedef enum csrng_app_cmd_id {
  kCsrngAppCmdInstantiate = 1,
  kCsrngAppCmdReseed = 2,
  kCsrngAppCmdGenerate = 3,
  kCsrngAppCmdUpdate = 4,
  kCsrngAppCmdUnisntantiate = 5,
} csrng_app_cmd_id_t;

/**
 * CSRNG application interface command header parameters.
 */
typedef struct csrng_app_cmd {
  /**
   * Application command.
   */
  csrng_app_cmd_id_t id;
  /**
   * Entropy source enable.
   *
   * Mapped to flag0 in the hardware command interface.
   */
  dif_csrng_entropy_src_toggle_t entropy_src_enable;
  /**
   * Seed material. Only used in `kCsrngAppCmdInstantiate`, `kCsrngAppCmdReseed`
   * and `kCsrngAppCmdUpdate` commands.
   */
  const dif_csrng_seed_material_t *seed_material;
  /**
   * Generate length. Specified as number of 128bit blocks.
   */
  uint32_t generate_len;
} csrng_app_cmd_t;

/**
 * Writes application command `cmd` to the CSRNG_CMD_REQ_REG register.
 * Returns the result of the operation.
 */
static dif_csrng_result_t write_application_command(
    const dif_csrng_t *csrng, const csrng_app_cmd_t *cmd) {
  if (csrng == NULL || cmd == NULL) {
    return kDifCsrngBadArg;
  }

  // The application command header is not specified as a register in the
  // hardware specification, so the fields are mapped here by hand. The
  // command register also accepts arbitrary 32bit data.
  const uint32_t kAppCmdBitFlag0 = 8;
  const bitfield_field32_t kAppCmdFieldCmdId = {.mask = 0xf, .index = 0};
  const bitfield_field32_t kAppCmdFieldCmdLen = {.mask = 0xf, .index = 4};
  const bitfield_field32_t kAppCmdFieldGlen = {.mask = 0x7ffff, .index = 12};

  uint32_t cmd_len =
      cmd->seed_material == NULL ? 0 : cmd->seed_material->seed_material_len;

  if (cmd_len & ~kAppCmdFieldCmdLen.mask) {
    return kDifCsrngBadArg;
  }

  // Build and write application command header.
  uint32_t reg = bitfield_field32_write(0, kAppCmdFieldCmdId, cmd->id);
  reg = bitfield_field32_write(reg, kAppCmdFieldCmdLen, cmd_len);
  reg = bitfield_bit32_write(reg, kAppCmdBitFlag0, cmd->entropy_src_enable);
  reg = bitfield_field32_write(reg, kAppCmdFieldGlen, cmd->generate_len);
  mmio_region_write32(csrng->params.base_addr, CSRNG_CMD_REQ_REG_OFFSET, reg);

  for (size_t i = 0; i < cmd_len; ++i) {
    mmio_region_write32(csrng->params.base_addr, CSRNG_CMD_REQ_REG_OFFSET,
                        cmd->seed_material->seed_material[i]);
  }
  return kDifCsrngOk;
}

/**
 * Reads the output data register status.
 */
static void get_output_status(const dif_csrng_t *csrng,
                              dif_csrng_output_status_t *status) {
  uint32_t reg =
      mmio_region_read32(csrng->params.base_addr, CSRNG_GENBITS_VLD_REG_OFFSET);
  status->valid_data =
      bitfield_bit32_read(reg, CSRNG_GENBITS_VLD_GENBITS_VLD_BIT);
  status->fips_mode =
      bitfield_bit32_read(reg, CSRNG_GENBITS_VLD_GENBITS_FIPS_BIT);
}

/**
 * Returns true if the data register has valid data.
 */
static bool is_output_ready(const dif_csrng_t *csrng) {
  dif_csrng_output_status_t status;
  get_output_status(csrng, &status);
  return status.valid_data;
}

dif_csrng_result_t dif_csrng_init(dif_csrng_params_t params,
                                  dif_csrng_t *csrng) {
  if (csrng == NULL) {
    return kDifCsrngBadArg;
  }
  *csrng = (dif_csrng_t){.params = params};
  return kDifCsrngOk;
}

dif_csrng_result_t dif_csrng_configure(const dif_csrng_t *csrng) {
  if (csrng == NULL) {
    return kDifCsrngBadArg;
  }
  mmio_region_write32(csrng->params.base_addr, CSRNG_CTRL_REG_OFFSET, 0xaaa);
  return kDifCsrngOk;
}

dif_csrng_result_t dif_csrng_instantiate(
    const dif_csrng_t *csrng, dif_csrng_entropy_src_toggle_t entropy_src_enable,
    const dif_csrng_seed_material_t *seed_material) {
  const csrng_app_cmd_t app_cmd = {
      .id = kCsrngAppCmdInstantiate,
      .entropy_src_enable = entropy_src_enable,
      .seed_material = seed_material,
      .generate_len = 0,
  };
  return write_application_command(csrng, &app_cmd);
}

dif_csrng_result_t dif_csrng_reseed(
    const dif_csrng_t *csrng, const dif_csrng_seed_material_t *seed_material) {
  const csrng_app_cmd_t app_cmd = {
      .id = kCsrngAppCmdReseed,
      .entropy_src_enable = false,
      .seed_material = seed_material,
      .generate_len = 0,
  };
  return write_application_command(csrng, &app_cmd);
}

dif_csrng_result_t dif_csrng_update(
    const dif_csrng_t *csrng, const dif_csrng_seed_material_t *seed_material) {
  const csrng_app_cmd_t app_cmd = {
      .id = kCsrngAppCmdUpdate,
      .entropy_src_enable = false,
      .seed_material = seed_material,
      .generate_len = 0,
  };
  return write_application_command(csrng, &app_cmd);
}

dif_csrng_result_t dif_csrng_generate_start(const dif_csrng_t *csrng,
                                            size_t len) {
  if (len == 0) {
    return kDifCsrngBadArg;
  }

  // Round up the number of 128bit blocks. Aligning with respect to uint32_t.
  // TODO(#6112): Consider using a canonical reference for alignment operations.
  const uint32_t num_128bit_blocks = (len + 3) / 4;

  const csrng_app_cmd_t app_cmd = {
      .id = kCsrngAppCmdGenerate,
      .entropy_src_enable = false,
      .seed_material = NULL,
      .generate_len = num_128bit_blocks,
  };
  return write_application_command(csrng, &app_cmd);
}

dif_csrng_result_t dif_csrng_generate_end(const dif_csrng_t *csrng,
                                          uint32_t *buf, size_t len) {
  if (csrng == NULL || buf == NULL) {
    return kDifCsrngBadArg;
  }

  // Wait until there is data ready.
  while (!is_output_ready(csrng)) {
  }

  for (size_t i = 0, rd_cnt = 0; i < len; ++i, ++rd_cnt) {
    // Block until there is more data available in the genbits buffer.
    if (rd_cnt == kCsrngGenBitsBufferSize) {
      while (!is_output_ready(csrng)) {
      }
      rd_cnt = 0;
    }
    buf[i] =
        mmio_region_read32(csrng->params.base_addr, CSRNG_GENBITS_REG_OFFSET);
  }
  return kDifCsrngOk;
}

dif_csrng_result_t dif_csrng_uninstantiate(const dif_csrng_t *csrng) {
  const csrng_app_cmd_t app_cmd = {
      .id = kCsrngAppCmdUnisntantiate,
      .entropy_src_enable = false,
      .seed_material = NULL,
      .generate_len = 0,
  };
  return write_application_command(csrng, &app_cmd);
}

dif_csrng_result_t dif_csrng_get_cmd_interface_status(
    const dif_csrng_t *csrng, dif_csrng_cmd_status_t *status) {
  if (csrng == NULL || status == NULL) {
    return kDifCsrngBadArg;
  }

  uint32_t reg =
      mmio_region_read32(csrng->params.base_addr, CSRNG_SW_CMD_STS_REG_OFFSET);
  bool cmd_ready = bitfield_bit32_read(reg, CSRNG_SW_CMD_STS_CMD_RDY_BIT);
  bool cmd_error = bitfield_bit32_read(reg, CSRNG_SW_CMD_STS_CMD_STS_BIT);

  // The function prioritizes error detection to avoid masking errors
  // when `cmd_ready` is set to true.
  if (cmd_error) {
    *status = kDifCsrngCmdStatusError;
    return kDifCsrngOk;
  }

  if (cmd_ready) {
    *status = kDifCsrngCmdStatusReady;
    return kDifCsrngOk;
  }

  *status = kDifCsrngCmdStatusBusy;
  return kDifCsrngOk;
}

dif_csrng_result_t dif_csrng_get_output_status(
    const dif_csrng_t *csrng, dif_csrng_output_status_t *status) {
  if (csrng == NULL || status == NULL) {
    return kDifCsrngBadArg;
  }
  get_output_status(csrng, status);
  return kDifCsrngOk;
}

DIF_WARN_UNUSED_RESULT
dif_csrng_result_t dif_csrng_get_internal_state(
    const dif_csrng_t *csrng, dif_csrng_internal_state_id_t instance_id,
    dif_csrng_internal_state_t *state) {
  if (csrng == NULL || state == NULL) {
    return kDifCsrngBadArg;
  }

  // Select the instance id to read the internal state from, request a state
  // machine halt, and wait for the internal registers to be ready to be read.
  uint32_t reg = bitfield_field32_write(
      0, CSRNG_INT_STATE_NUM_INT_STATE_NUM_FIELD, instance_id);
  mmio_region_write32(csrng->params.base_addr, CSRNG_INT_STATE_NUM_REG_OFFSET,
                      reg);

  // Read the internal state.
  state->reseed_counter = mmio_region_read32(csrng->params.base_addr,
                                             CSRNG_INT_STATE_VAL_REG_OFFSET);

  for (size_t i = 0; i < ARRAYSIZE(state->v); ++i) {
    state->v[i] = mmio_region_read32(csrng->params.base_addr,
                                     CSRNG_INT_STATE_VAL_REG_OFFSET);
  }

  for (size_t i = 0; i < ARRAYSIZE(state->key); ++i) {
    state->key[i] = mmio_region_read32(csrng->params.base_addr,
                                       CSRNG_INT_STATE_VAL_REG_OFFSET);
  }

  uint32_t flags = mmio_region_read32(csrng->params.base_addr,
                                      CSRNG_INT_STATE_VAL_REG_OFFSET);

  // The following bit indexes are defined in
  // https://docs.opentitan.org/hw/ip/csrng/doc/#working-state-values
  state->instantiated = bitfield_bit32_read(flags, /*bit_index=*/0u);
  state->fips_compliance = bitfield_bit32_read(flags, /*bit_index=*/1u);

  return kDifCsrngOk;
}
