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

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

#include "csrng_regs.h"        // Generated
#include "edn_regs.h"          // Generated
#include "entropy_src_regs.h"  // Generated
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"

enum {
  kBaseCsrng = TOP_EARLGREY_CSRNG_BASE_ADDR,
  kBaseEntropySrc = TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR,
  kBaseEdn0 = TOP_EARLGREY_EDN0_BASE_ADDR,
  kBaseEdn1 = TOP_EARLGREY_EDN1_BASE_ADDR,

  /**
   * CSRNG genbits buffer size in uint32_t words.
   */
  kEntropyCsrngBitsBufferNumWords = 4,
};

/**
 * Supported CSRNG application commands.
 * See https://docs.opentitan.org/hw/ip/csrng/doc/#command-header for
 * details.
 */
// TODO(#14542): Harden csrng/edn command fields.
typedef enum entropy_csrng_op {
  kEntropyDrbgOpInstantiate = 1,
  kEntropyDrbgOpReseed = 2,
  kEntropyDrbgOpGenerate = 3,
  kEntropyDrbgOpUpdate = 4,
  kEntropyDrbgOpUnisntantiate = 5,
} entropy_csrng_op_t;

/**
 * CSRNG application interface command header parameters.
 */
typedef struct entropy_csrng_cmd {
  /**
   * Application command ID.
   */
  entropy_csrng_op_t id;
  /**
   * Entropy source enable.
   *
   * Mapped to flag0 in the hardware command interface.
   */
  hardened_bool_t disable_trng_input;
  const entropy_seed_material_t *seed_material;
  /**
   * Generate length. Specified as number of 128bit blocks.
   */
  uint32_t generate_len;
} entropy_csrng_cmd_t;

/**
 * Entropy complex configuration modes.
 *
 * Each enum value is used a confiugration index in `kEntropyComplexConfigs`.
 */
typedef enum entropy_complex_config_id {
  /**
   * Entropy complex in continuous mode. This is the default runtime
   * configuration.
   */
  kEntropyComplexConfigIdContinuous,
  kEntropyComplexConfigIdNumEntries,
} entropy_complex_config_id_t;

/**
 * EDN configuration settings.
 */
typedef struct edn_config {
  /**
   * Base address of the EDN block.
   */
  uint32_t base_address;
  /**
   * Number of generate calls between reseed commands.
   */
  uint32_t reseed_interval;
  /**
   * Downstream CSRNG instantiate command configuration.
   */
  entropy_csrng_cmd_t instantiate;
  /**
   * Downstream CSRNG generate command configuration.
   */
  entropy_csrng_cmd_t generate;
  /**
   * Downstream CSRNG reseed command configuration.
   */
  entropy_csrng_cmd_t reseed;
} edn_config_t;

/**
 * Entropy complex configuration settings.
 *
 * Contains configuration paramenters for entropy_src, csrng, edn0 and edn1.
 */
typedef struct entropy_complex_config {
  /**
   * Configuration identifier.
   */
  entropy_complex_config_id_t id;
  /**
   * If set, FIPS compliant entropy will be generated by this module after being
   * processed by an SP 800-90B compliant conditioning function.
   */
  multi_bit_bool_t fips_enable;
  /**
   * If set, entropy will be routed to a firmware-visible register instead of
   * being distributed to other hardware IPs.
   */
  multi_bit_bool_t route_to_firmware;
  /**
   * If set, raw entropy will be sent to CSRNG, bypassing the conditioner block
   * and disabling the FIPS hardware generated flag.
   */
  multi_bit_bool_t bypass_conditioner;
  /**
   * Enables single bit entropy mode.
   */
  multi_bit_bool_t single_bit_mode;
  /**
   * The size of the window used for health tests.
   */
  uint16_t fips_test_window_size;
  /**
   * The number of health test failures that must occur before an alert is
   * triggered. When set to 0, alerts are disabled.
   */
  uint16_t alert_threshold;
  /**
   * EDN0 configuration.
   */
  edn_config_t edn0;
  /**
   * EDN1 configuration.
   */
  edn_config_t edn1;
} entropy_complex_config_t;

// Entropy complex configuration table. This is expected to be fixed at build
// time. For this reason, it is not recommended to use this table in a ROM
// target unless the values are known to work. In other words, only use in
// mutable code partitions.
static const entropy_complex_config_t
    kEntropyComplexConfigs[kEntropyComplexConfigIdNumEntries] = {
        [kEntropyComplexConfigIdContinuous] =
            {
                .fips_enable = kMultiBitBool4True,
                .route_to_firmware = kMultiBitBool4False,
                .bypass_conditioner = kMultiBitBool4False,
                .single_bit_mode = kMultiBitBool4False,
                .fips_test_window_size = 0x200,
                .alert_threshold = 2,
                .edn0 =
                    {
                        .base_address = kBaseEdn0,
                        .reseed_interval = 32,
                        .instantiate =
                            {
                                .id = kEntropyDrbgOpInstantiate,
                                .disable_trng_input = kHardenedBoolFalse,
                                .seed_material = NULL,
                                .generate_len = 0,
                            },
                        .generate =
                            {
                                .id = kEntropyDrbgOpGenerate,
                                .disable_trng_input = kHardenedBoolFalse,
                                .seed_material = NULL,
                                .generate_len = 8,
                            },
                        .reseed =
                            {
                                .id = kEntropyDrbgOpReseed,
                                .disable_trng_input = kHardenedBoolFalse,
                                .seed_material = NULL,
                                .generate_len = 0,
                            },
                    },
                .edn1 =
                    {
                        .base_address = kBaseEdn1,
                        .reseed_interval = 4,
                        .instantiate =
                            {
                                .id = kEntropyDrbgOpInstantiate,
                                .disable_trng_input = kHardenedBoolFalse,
                                .seed_material = NULL,
                                .generate_len = 0,
                            },
                        .generate =
                            {
                                .id = kEntropyDrbgOpGenerate,
                                .seed_material = NULL,
                                .generate_len = 1,
                            },
                        .reseed =
                            {
                                .id = kEntropyDrbgOpReseed,
                                .disable_trng_input = kHardenedBoolFalse,
                                .seed_material = NULL,
                                .generate_len = 0,
                            },
                    },
            },
};

OT_WARN_UNUSED_RESULT
static status_t csrng_send_app_cmd(uint32_t reg_address,
                                   entropy_csrng_cmd_t cmd) {
  uint32_t reg;
  bool cmd_ready;
  do {
    reg = abs_mmio_read32(kBaseCsrng + CSRNG_SW_CMD_STS_REG_OFFSET);
    cmd_ready = bitfield_bit32_read(reg, CSRNG_SW_CMD_STS_CMD_RDY_BIT);
  } while (!cmd_ready);

#define ENTROPY_CMD(m, i) ((bitfield_field32_t){.mask = m, .index = i})
  // 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.
  static const bitfield_field32_t kAppCmdFieldFlag0 = ENTROPY_CMD(0xf, 8);
  static const bitfield_field32_t kAppCmdFieldCmdId = ENTROPY_CMD(0xf, 0);
  static const bitfield_field32_t kAppCmdFieldCmdLen = ENTROPY_CMD(0xf, 4);
  static const bitfield_field32_t kAppCmdFieldGlen = ENTROPY_CMD(0x7ffff, 12);
#undef ENTROPY_CMD

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

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

  // TODO: Consider removing this since the driver will be constructing these
  // commands internally.
  // Ensure the `seed_material` array is word-aligned, so it can be loaded to a
  // CPU register with natively aligned loads.
  if (cmd.seed_material != NULL &&
      misalignment32_of((uintptr_t)cmd.seed_material->data) != 0) {
    return INTERNAL();
  }

  // Build and write application command header.
  reg = bitfield_field32_write(0, kAppCmdFieldCmdId, cmd.id);
  reg = bitfield_field32_write(reg, kAppCmdFieldCmdLen, cmd_len);
  reg = bitfield_field32_write(reg, kAppCmdFieldGlen, cmd.generate_len);

  if (launder32(cmd.disable_trng_input) == kHardenedBoolTrue) {
    reg = bitfield_field32_write(reg, kAppCmdFieldFlag0, kMultiBitBool4True);
  }

  abs_mmio_write32(reg_address, reg);

  for (size_t i = 0; i < cmd_len; ++i) {
    abs_mmio_write32(reg_address, cmd.seed_material->data[i]);
  }
  return OK_STATUS();
}

/**
 * Enables the CSRNG block with the SW application and internal state registers
 * enabled.
 */
static void csrng_configure(void) {
  uint32_t reg =
      bitfield_field32_write(0, CSRNG_CTRL_ENABLE_FIELD, kMultiBitBool4True);
  reg = bitfield_field32_write(reg, CSRNG_CTRL_SW_APP_ENABLE_FIELD,
                               kMultiBitBool4True);
  reg = bitfield_field32_write(reg, CSRNG_CTRL_READ_INT_STATE_FIELD,
                               kMultiBitBool4True);
  abs_mmio_write32(kBaseCsrng + CSRNG_CTRL_REG_OFFSET, reg);
}

/**
 * Stops a given EDN instance.
 *
 * It also resets the EDN CSRNG command buffer to avoid synchronization issues
 * with the upstream CSRNG instance.
 *
 * @param edn_address The based address of the target EDN block.
 */
static void edn_stop(uint32_t edn_address) {
  // FIFO clear is only honored if edn is enabled. This is needed to avoid
  // synchronization issues with the upstream CSRNG instance.
  uint32_t reg = abs_mmio_read32(edn_address + EDN_CTRL_REG_OFFSET);
  abs_mmio_write32(edn_address + EDN_CTRL_REG_OFFSET,
                   bitfield_field32_write(reg, EDN_CTRL_CMD_FIFO_RST_FIELD,
                                          kMultiBitBool4True));

  // Disable EDN and restore the FIFO clear at the same time so that no rogue
  // command can get in after the clear above.
  abs_mmio_write32(edn_address + EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
}

/**
 * Blocks until EDN instance is ready to execute a new CSNRG command.
 *
 * @param edn_address EDN base address.
 * @returns an error if the EDN error status bit is set.
 */
OT_WARN_UNUSED_RESULT
static status_t edn_ready_block(uint32_t edn_address) {
  uint32_t reg;
  do {
    reg = abs_mmio_read32(edn_address + EDN_SW_CMD_STS_REG_OFFSET);
  } while (!bitfield_bit32_read(reg, EDN_SW_CMD_STS_CMD_RDY_BIT));

  if (bitfield_bit32_read(reg, EDN_SW_CMD_STS_CMD_STS_BIT)) {
    return INTERNAL();
  }
  return OK_STATUS();
}

/**
 * Configures EDN instance based on `config` options.
 *
 * @param config EDN configuration options.
 * @returns error on failure.
 */
OT_WARN_UNUSED_RESULT
static status_t edn_configure(const edn_config_t *config) {
  TRY(csrng_send_app_cmd(config->base_address + EDN_RESEED_CMD_REG_OFFSET,
                         config->reseed));
  TRY(csrng_send_app_cmd(config->base_address + EDN_GENERATE_CMD_REG_OFFSET,
                         config->generate));
  abs_mmio_write32(
      config->base_address + EDN_MAX_NUM_REQS_BETWEEN_RESEEDS_REG_OFFSET,
      config->reseed_interval);

  uint32_t reg =
      bitfield_field32_write(0, EDN_CTRL_EDN_ENABLE_FIELD, kMultiBitBool4True);
  reg = bitfield_field32_write(reg, EDN_CTRL_AUTO_REQ_MODE_FIELD,
                               kMultiBitBool4True);
  abs_mmio_write32(config->base_address + EDN_CTRL_REG_OFFSET, reg);

  TRY(edn_ready_block(config->base_address));
  TRY(csrng_send_app_cmd(config->base_address + EDN_SW_CMD_REQ_REG_OFFSET,
                         config->instantiate));
  return edn_ready_block(config->base_address);
}

/**
 * Stops the current mode of operation and disables the entropy_src module.
 *
 * All configuration registers are set to their reset values to avoid
 * synchronization issues with internal FIFOs.
 */
static void entropy_src_stop(void) {
  abs_mmio_write32(kBaseEntropySrc + ENTROPY_SRC_MODULE_ENABLE_REG_OFFSET,
                   ENTROPY_SRC_MODULE_ENABLE_REG_RESVAL);

  // Set default values for other critical registers to avoid synchronization
  // issues.
  abs_mmio_write32(kBaseEntropySrc + ENTROPY_SRC_ENTROPY_CONTROL_REG_OFFSET,
                   ENTROPY_SRC_ENTROPY_CONTROL_REG_RESVAL);
  abs_mmio_write32(kBaseEntropySrc + ENTROPY_SRC_CONF_REG_OFFSET,
                   ENTROPY_SRC_CONF_REG_RESVAL);
  abs_mmio_write32(kBaseEntropySrc + ENTROPY_SRC_HEALTH_TEST_WINDOWS_REG_OFFSET,
                   ENTROPY_SRC_HEALTH_TEST_WINDOWS_REG_RESVAL);
  abs_mmio_write32(kBaseEntropySrc + ENTROPY_SRC_ALERT_THRESHOLD_REG_OFFSET,
                   ENTROPY_SRC_ALERT_THRESHOLD_REG_RESVAL);
}

/**
 * Disables the entropy complex.
 *
 * The order of operations is important to avoid synchronization issues across
 * blocks. For Example, EDN has FIFOs used to send commands to the downstream
 * CSRNG instances. Such FIFOs are not cleared when EDN is reconfigured, and an
 * explicit clear FIFO command needs to be set by software (see #14506). There
 * may be additional race conditions for downstream blocks that are
 * processing requests from an upstream endpoint (e.g. entropy_src processing a
 * request from CSRNG, or CSRNG processing a request from EDN). To avoid these
 * issues, it is recommended to first disable EDN, then CSRNG and entropy_src
 * last.
 *
 * See hw/ip/csrng/doc/_index.md#module-enable-and-disable for more details.
 */
static void entropy_complex_stop_all(void) {
  edn_stop(kBaseEdn0);
  edn_stop(kBaseEdn1);
  abs_mmio_write32(kBaseCsrng + CSRNG_CTRL_REG_OFFSET, CSRNG_CTRL_REG_RESVAL);
  entropy_src_stop();
}

/**
 * Configures the entropy_src with based on `config` options.
 *
 * @param config Entropy Source configuration options.
 * @return error on failure.
 */
OT_WARN_UNUSED_RESULT
static status_t entropy_src_configure(const entropy_complex_config_t *config) {
  // Control register configuration.
  uint32_t reg = bitfield_field32_write(
      0, ENTROPY_SRC_ENTROPY_CONTROL_ES_ROUTE_FIELD, config->route_to_firmware);
  reg = bitfield_field32_write(reg, ENTROPY_SRC_ENTROPY_CONTROL_ES_TYPE_FIELD,
                               config->bypass_conditioner);
  abs_mmio_write32(kBaseEntropySrc + ENTROPY_SRC_ENTROPY_CONTROL_REG_OFFSET,
                   reg);

  // Config register configuration
  reg = bitfield_field32_write(0, ENTROPY_SRC_CONF_FIPS_ENABLE_FIELD,
                               config->fips_enable);
  reg = bitfield_field32_write(reg,
                               ENTROPY_SRC_CONF_ENTROPY_DATA_REG_ENABLE_FIELD,
                               config->route_to_firmware);
  reg = bitfield_field32_write(reg, ENTROPY_SRC_CONF_THRESHOLD_SCOPE_FIELD,
                               kMultiBitBool4False);
  reg = bitfield_field32_write(reg, ENTROPY_SRC_CONF_RNG_BIT_ENABLE_FIELD,
                               config->single_bit_mode);
  reg = bitfield_field32_write(reg, ENTROPY_SRC_CONF_RNG_BIT_SEL_FIELD, 0);
  abs_mmio_write32(kBaseEntropySrc + ENTROPY_SRC_CONF_REG_OFFSET, reg);

  // Configure health test windw. Conditioning bypass is not supported.
  abs_mmio_write32(
      kBaseEntropySrc + ENTROPY_SRC_HEALTH_TEST_WINDOWS_REG_OFFSET,
      bitfield_field32_write(ENTROPY_SRC_HEALTH_TEST_WINDOWS_REG_RESVAL,
                             ENTROPY_SRC_HEALTH_TEST_WINDOWS_FIPS_WINDOW_FIELD,
                             config->fips_test_window_size));

  // Configure alert threshold
  reg = bitfield_field32_write(
      0, ENTROPY_SRC_ALERT_THRESHOLD_ALERT_THRESHOLD_FIELD,
      config->alert_threshold);
  reg = bitfield_field32_write(
      reg, ENTROPY_SRC_ALERT_THRESHOLD_ALERT_THRESHOLD_INV_FIELD,
      ~config->alert_threshold);
  abs_mmio_write32(kBaseEntropySrc + ENTROPY_SRC_ALERT_THRESHOLD_REG_OFFSET,
                   reg);

  abs_mmio_write32(kBaseEntropySrc + ENTROPY_SRC_MODULE_ENABLE_REG_OFFSET,
                   kMultiBitBool4True);

  // TODO: Add FI checks.
  return OK_STATUS();
}

status_t entropy_complex_init(void) {
  entropy_complex_stop_all();

  const entropy_complex_config_t *config =
      &kEntropyComplexConfigs[kEntropyComplexConfigIdContinuous];
  if (launder32(config->id) != kEntropyComplexConfigIdContinuous) {
    return INTERNAL();
  }

  // TODO: Add health check configuration.

  TRY(entropy_src_configure(config));
  csrng_configure();
  TRY(edn_configure(&config->edn0));
  return edn_configure(&config->edn1);
}

status_t entropy_csrng_instantiate(
    hardened_bool_t disable_trng_input,
    const entropy_seed_material_t *seed_material) {
  return csrng_send_app_cmd(kBaseCsrng + CSRNG_CMD_REQ_REG_OFFSET,
                            (entropy_csrng_cmd_t){
                                .id = kEntropyDrbgOpInstantiate,
                                .disable_trng_input = disable_trng_input,
                                .seed_material = seed_material,
                                .generate_len = 0,
                            });
}

status_t entropy_csrng_reseed(hardened_bool_t disable_trng_input,
                              const entropy_seed_material_t *seed_material) {
  return csrng_send_app_cmd(kBaseCsrng + CSRNG_CMD_REQ_REG_OFFSET,
                            (entropy_csrng_cmd_t){
                                .id = kEntropyDrbgOpReseed,
                                .disable_trng_input = disable_trng_input,
                                .seed_material = seed_material,
                                .generate_len = 0,
                            });
}

status_t entropy_csrng_update(const entropy_seed_material_t *seed_material) {
  return csrng_send_app_cmd(kBaseCsrng + CSRNG_CMD_REQ_REG_OFFSET,
                            (entropy_csrng_cmd_t){
                                .id = kEntropyDrbgOpUpdate,
                                .seed_material = seed_material,
                                .generate_len = 0,
                            });
}

status_t entropy_csrng_generate_start(
    const entropy_seed_material_t *seed_material, size_t len) {
  // 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;
  return csrng_send_app_cmd(kBaseCsrng + CSRNG_CMD_REQ_REG_OFFSET,
                            (entropy_csrng_cmd_t){
                                .id = kEntropyDrbgOpGenerate,
                                .seed_material = seed_material,
                                .generate_len = num_128bit_blocks,
                            });
}

status_t entropy_csrng_generate_data_get(uint32_t *buf, size_t len) {
  for (size_t i = 0; i < len; ++i) {
    // Block until there is more data available in the genbits buffer. CSRNG
    // generates data in 128bit chunks (i.e. 4 words).
    static_assert(kEntropyCsrngBitsBufferNumWords == 4,
                  "kEntropyCsrngBitsBufferNumWords must be a power of 2.");
    if (i & (kEntropyCsrngBitsBufferNumWords - 1)) {
      uint32_t reg;
      do {
        reg = abs_mmio_read32(kBaseCsrng + CSRNG_GENBITS_VLD_REG_OFFSET);
      } while (!bitfield_bit32_read(reg, CSRNG_GENBITS_VLD_GENBITS_VLD_BIT));
    }
    buf[i] = abs_mmio_read32(kBaseCsrng + CSRNG_GENBITS_REG_OFFSET);
  }
  return OK_STATUS();
}

status_t entropy_csrng_generate(const entropy_seed_material_t *seed_material,
                                uint32_t *buf, size_t len) {
  TRY(entropy_csrng_generate_start(seed_material, len));
  return entropy_csrng_generate_data_get(buf, len);
}

status_t entropy_csrng_uninstantiate(void) {
  return csrng_send_app_cmd(kBaseCsrng + CSRNG_CMD_REQ_REG_OFFSET,
                            (entropy_csrng_cmd_t){
                                .id = kEntropyDrbgOpUpdate,
                                .seed_material = NULL,
                                .generate_len = 0,
                            });
}
