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

#include <assert.h>

#include "keymgr_regs.h"  // Generated.

/**
 * Address spaces of SEALING_SW_BINDING_N, SALT_N, SW_SHARE0_OUTPUT_N, and
 * SW_SHARE1_OUTPUT_N registers must be contiguous to be able to use
 * `mmio_region_memcpy_to/from_mmio32()`.
 */
static_assert(KEYMGR_SEALING_SW_BINDING_1_REG_OFFSET ==
                  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 4,
              "SEALING_SW_BINDING_N registers must be contiguous.");
static_assert(KEYMGR_SEALING_SW_BINDING_2_REG_OFFSET ==
                  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 8,
              "SEALING_SW_BINDING_N registers must be contiguous.");
static_assert(KEYMGR_SEALING_SW_BINDING_3_REG_OFFSET ==
                  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 12,
              "SEALING_SW_BINDING_N registers must be contiguous.");
// TODO: Uncomment when lowRISC/opentitan#5194 is completed.
// TODO: Consider defining a macro once all assertions are enabled.
// static_assert(KEYMGR_SEALING_SW_BINDING_4_REG_OFFSET ==
//                   KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 16,
//               "SEALING_SW_BINDING_N registers must be contiguous.");
// static_assert(KEYMGR_SEALING_SW_BINDING_5_REG_OFFSET ==
//                   KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 20,
//               "SEALING_SW_BINDING_N registers must be contiguous.");
// static_assert(KEYMGR_SEALING_SW_BINDING_6_REG_OFFSET ==
//                   KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 24,
//               "SEALING_SW_BINDING_N registers must be contiguous.");
// static_assert(KEYMGR_SEALING_SW_BINDING_7_REG_OFFSET ==
//                   KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 28,
//               "SEALING_SW_BINDING_N registers must be contiguous.");

static_assert(KEYMGR_SALT_1_REG_OFFSET == KEYMGR_SALT_0_REG_OFFSET + 4,
              "SALT_N registers must be contiguous.");
static_assert(KEYMGR_SALT_2_REG_OFFSET == KEYMGR_SALT_0_REG_OFFSET + 8,
              "SALT_N registers must be contiguous.");
static_assert(KEYMGR_SALT_3_REG_OFFSET == KEYMGR_SALT_0_REG_OFFSET + 12,
              "SALT_N registers must be contiguous.");
// TODO: Uncomment when lowRISC/opentitan#5194 is completed.
// static_assert(KEYMGR_SALT_4_REG_OFFSET ==
//                   KEYMGR_SALT_0_REG_OFFSET + 16,
//               "SALT_N registers must be contiguous.");
// static_assert(KEYMGR_SALT_5_REG_OFFSET ==
//                   KEYMGR_SALT_0_REG_OFFSET + 20,
//               "SALT_N registers must be contiguous.");
// static_assert(KEYMGR_SALT_6_REG_OFFSET ==
//                   KEYMGR_SALT_0_REG_OFFSET + 24,
//               "SALT_N registers must be contiguous.");
// static_assert(KEYMGR_SALT_7_REG_OFFSET ==
//                   KEYMGR_SALT_0_REG_OFFSET + 28,
//               "SALT_N registers must be contiguous.");

static_assert(KEYMGR_SW_SHARE0_OUTPUT_1_REG_OFFSET ==
                  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 4,
              "SW_SHARE0_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE0_OUTPUT_2_REG_OFFSET ==
                  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 8,
              "SW_SHARE0_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE0_OUTPUT_3_REG_OFFSET ==
                  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 12,
              "SW_SHARE0_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE0_OUTPUT_4_REG_OFFSET ==
                  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 16,
              "SW_SHARE0_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE0_OUTPUT_5_REG_OFFSET ==
                  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 20,
              "SW_SHARE0_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE0_OUTPUT_6_REG_OFFSET ==
                  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 24,
              "SW_SHARE0_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE0_OUTPUT_7_REG_OFFSET ==
                  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 28,
              "SW_SHARE0_OUTPUT_N registers must be contiguous.");

static_assert(KEYMGR_SW_SHARE1_OUTPUT_1_REG_OFFSET ==
                  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 4,
              "SW_SHARE1_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE1_OUTPUT_2_REG_OFFSET ==
                  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 8,
              "SW_SHARE1_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE1_OUTPUT_3_REG_OFFSET ==
                  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 12,
              "SW_SHARE1_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE1_OUTPUT_4_REG_OFFSET ==
                  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 16,
              "SW_SHARE1_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE1_OUTPUT_5_REG_OFFSET ==
                  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 20,
              "SW_SHARE1_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE1_OUTPUT_6_REG_OFFSET ==
                  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 24,
              "SW_SHARE1_OUTPUT_N registers must be contiguous.");
static_assert(KEYMGR_SW_SHARE1_OUTPUT_7_REG_OFFSET ==
                  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 28,
              "SW_SHARE1_OUTPUT_N registers must be contiguous.");

/**
 * Error code constants of `dif_keymgr_status_code_t` are masks for the bits of
 * ERR_CODE register shifted left by 1.
 */
static_assert(kDifKeymgrStatusCodeInvalidOperation >> 1 ==
                  1 << KEYMGR_ERR_CODE_INVALID_OP_BIT,
              "Layout of ERR_CODE register changed.");
static_assert(kDifKeymgrStatusCodeInvalidKmacInput >> 1 ==
                  1 << KEYMGR_ERR_CODE_INVALID_KMAC_INPUT_BIT,
              "Layout of ERR_CODE register changed.");

/**
 * Checks if the key manager is ready for a new operation, i.e. it is idle and
 * the CONFIG register is unlocked.
 */
OT_WARN_UNUSED_RESULT
static bool is_ready(const dif_keymgr_t *keymgr) {
  // Keymgr must be idle and the CONTROL register must be writable.
  uint32_t reg_op_status =
      mmio_region_read32(keymgr->params.base_addr, KEYMGR_OP_STATUS_REG_OFFSET);
  if (bitfield_field32_read(reg_op_status, KEYMGR_OP_STATUS_STATUS_FIELD) !=
      KEYMGR_OP_STATUS_STATUS_VALUE_IDLE) {
    return false;
  }
  uint32_t reg_cfg_regwen = mmio_region_read32(keymgr->params.base_addr,
                                               KEYMGR_CFG_REGWEN_REG_OFFSET);
  return bitfield_bit32_read(reg_cfg_regwen, KEYMGR_CFG_REGWEN_EN_BIT);
}

/**
 * Max key version register information for a state transition.
 */
typedef struct max_key_version_reg_info {
  /**
   * Whether max key version must be set for this transition or not.
   */
  bool is_required;
  /**
   * Max key version register offset to use.
   */
  uint32_t reg_offset;
  /**
   * Write-enable register offset to use.
   */
  uint32_t wen_reg_offset;
  /**
   * Write-enable bit index.
   */
  bitfield_bit32_index_t wen_bit_index;
} max_key_version_reg_info_t;

/**
 * Returns max key version register information for transitioning from a state.
 */
OT_WARN_UNUSED_RESULT
static bool get_max_key_version_reg_info_for_next_state(
    uint32_t cur_state, max_key_version_reg_info_t *reg_info) {
  switch (cur_state) {
    case KEYMGR_WORKING_STATE_STATE_VALUE_INIT:
      *reg_info = (max_key_version_reg_info_t){
          .is_required = true,
          .reg_offset = KEYMGR_MAX_CREATOR_KEY_VER_SHADOWED_REG_OFFSET,
          .wen_reg_offset = KEYMGR_MAX_CREATOR_KEY_VER_REGWEN_REG_OFFSET,
          .wen_bit_index = KEYMGR_MAX_CREATOR_KEY_VER_REGWEN_EN_BIT,
      };
      return true;
    case KEYMGR_WORKING_STATE_STATE_VALUE_CREATOR_ROOT_KEY:
      *reg_info = (max_key_version_reg_info_t){
          .is_required = true,
          .reg_offset = KEYMGR_MAX_OWNER_INT_KEY_VER_SHADOWED_REG_OFFSET,
          .wen_reg_offset = KEYMGR_MAX_OWNER_INT_KEY_VER_REGWEN_REG_OFFSET,
          .wen_bit_index = KEYMGR_MAX_OWNER_INT_KEY_VER_REGWEN_EN_BIT,
      };
      return true;
    case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_INTERMEDIATE_KEY:
      *reg_info = (max_key_version_reg_info_t){
          .is_required = true,
          .reg_offset = KEYMGR_MAX_OWNER_KEY_VER_SHADOWED_REG_OFFSET,
          .wen_reg_offset = KEYMGR_MAX_OWNER_KEY_VER_REGWEN_REG_OFFSET,
          .wen_bit_index = KEYMGR_MAX_OWNER_KEY_VER_REGWEN_EN_BIT,
      };
      return true;
    case KEYMGR_WORKING_STATE_STATE_VALUE_RESET:
    case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_KEY:
    case KEYMGR_WORKING_STATE_STATE_VALUE_DISABLED:
    case KEYMGR_WORKING_STATE_STATE_VALUE_INVALID:
      *reg_info = (max_key_version_reg_info_t){
          .is_required = false,
      };
      return true;
    default:
      return false;
  }
}

/**
 * Parameters for starting a key manager operation.
 *
 * Values of the members must be the actual values that will be written to the
 * CONTROL register.
 */
typedef struct start_operation_params {
  /**
   * Destination for this operation.
   */
  uint32_t dest;
  /**
   * Operation to start.
   */
  uint32_t op;
} start_operation_params_t;

/**
 * Starts a key manager operation.
 */
static void start_operation(const dif_keymgr_t *keymgr,
                            start_operation_params_t params) {
  uint32_t reg_control =
      bitfield_field32_write(0, KEYMGR_CONTROL_DEST_SEL_FIELD, params.dest);
  reg_control = bitfield_field32_write(
      reg_control, KEYMGR_CONTROL_OPERATION_FIELD, params.op);
  reg_control =
      bitfield_bit32_write(reg_control, KEYMGR_CONTROL_START_BIT, true);
  mmio_region_write32(keymgr->params.base_addr, KEYMGR_CONTROL_REG_OFFSET,
                      reg_control);
}

/**
 * Returns the bit index for a given IRQ.
 */
OT_WARN_UNUSED_RESULT
static bool get_irq_bit_index(dif_keymgr_irq_t irq,
                              bitfield_bit32_index_t *bit_index) {
  switch (irq) {
    case kDifKeymgrIrqDone:
      *bit_index = KEYMGR_INTR_COMMON_OP_DONE_BIT;
      return true;
    default:
      return false;
  }
}

/**
 * Checks if a value is a valid `dif_keymgr_toggle_t` and converts it to `bool`.
 */
OT_WARN_UNUSED_RESULT
static bool toggle_to_bool(dif_keymgr_toggle_t val, bool *val_bool) {
  switch (val) {
    case kDifKeymgrToggleEnabled:
      *val_bool = true;
      break;
    case kDifKeymgrToggleDisabled:
      *val_bool = false;
      break;
    default:
      return false;
  }
  return true;
}

/**
 * Converts a `bool` to `dif_keymgr_toggle_t`.
 */
static dif_keymgr_toggle_t bool_to_toggle(bool val) {
  return val ? kDifKeymgrToggleEnabled : kDifKeymgrToggleDisabled;
}

dif_keymgr_result_t dif_keymgr_init(dif_keymgr_params_t params,
                                    dif_keymgr_t *keymgr) {
  if (keymgr == NULL) {
    return kDifKeymgrBadArg;
  }

  *keymgr = (dif_keymgr_t){.params = params};

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_configure(const dif_keymgr_t *keymgr,
                                         dif_keymgr_config_t config) {
  if (keymgr == NULL) {
    return kDifKeymgrBadArg;
  }

  uint32_t reg_val =
      bitfield_field32_write(0, KEYMGR_RESEED_INTERVAL_SHADOWED_VAL_FIELD,
                             config.entropy_reseed_interval);
  mmio_region_write32_shadowed(keymgr->params.base_addr,
                               KEYMGR_RESEED_INTERVAL_SHADOWED_REG_OFFSET,
                               reg_val);

  return kDifKeymgrOk;
}

dif_keymgr_lockable_result_t dif_keymgr_advance_state(
    const dif_keymgr_t *keymgr, const dif_keymgr_state_params_t *params) {
  if (keymgr == NULL) {
    return kDifKeymgrLockableBadArg;
  }

  if (!is_ready(keymgr)) {
    return kDifKeymgrLockableLocked;
  }

  // Get current state and determine if we need to set the max key version and
  // sw binding value.
  max_key_version_reg_info_t max_key_ver_reg_info;
  uint32_t reg_working_state = mmio_region_read32(
      keymgr->params.base_addr, KEYMGR_WORKING_STATE_REG_OFFSET);
  if (!get_max_key_version_reg_info_for_next_state(
          (bitfield_field32_read(reg_working_state,
                                 KEYMGR_WORKING_STATE_STATE_FIELD)),
          &max_key_ver_reg_info)) {
    return kDifKeymgrLockableError;
  }

  // Set the binding value and max key version if keymgr is going to
  // transition to an operational state.
  if (max_key_ver_reg_info.is_required) {
    if (params == NULL) {
      return kDifKeymgrLockableBadArg;
    }

    // Check if SEALING_SW_BINDING_N registers are locked
    uint32_t reg_sw_binding_wen = mmio_region_read32(
        keymgr->params.base_addr, KEYMGR_SW_BINDING_REGWEN_REG_OFFSET);
    if (!bitfield_bit32_read(reg_sw_binding_wen,
                             KEYMGR_SW_BINDING_REGWEN_EN_BIT)) {
      return kDifKeymgrLockableLocked;
    }

    // Check if MAX_*_KEY_VER register is locked.
    uint32_t reg_max_key_ver_wen = mmio_region_read32(
        keymgr->params.base_addr, max_key_ver_reg_info.wen_reg_offset);
    if (!bitfield_bit32_read(reg_max_key_ver_wen,
                             max_key_ver_reg_info.wen_bit_index)) {
      return kDifKeymgrLockableLocked;
    }

    // Write and lock (rw0c) the software binding value. This register is
    // unlocked by hardware upon a successful state transition.
    mmio_region_memcpy_to_mmio32(
        keymgr->params.base_addr, KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET,
        params->binding_value, sizeof(params->binding_value));
    mmio_region_write32(keymgr->params.base_addr,
                        KEYMGR_SW_BINDING_REGWEN_REG_OFFSET, 0);

    // Write and lock (rw0c) the max key version.
    mmio_region_write32_shadowed(keymgr->params.base_addr,
                                 max_key_ver_reg_info.reg_offset,
                                 params->max_key_version);
    mmio_region_write32(keymgr->params.base_addr,
                        max_key_ver_reg_info.wen_reg_offset, 0);
  } else if (params != NULL) {
    return kDifKeymgrLockableBadArg;
  }

  // Advance state.
  start_operation(keymgr, (start_operation_params_t){
                              .dest = KEYMGR_CONTROL_DEST_SEL_VALUE_NONE,
                              .op = KEYMGR_CONTROL_OPERATION_VALUE_ADVANCE,
                          });

  return kDifKeymgrLockableOk;
}

dif_keymgr_lockable_result_t dif_keymgr_disable(const dif_keymgr_t *keymgr) {
  if (keymgr == NULL) {
    return kDifKeymgrLockableBadArg;
  }

  if (!is_ready(keymgr)) {
    return kDifKeymgrLockableLocked;
  }

  // Disable key manager.
  start_operation(keymgr, (start_operation_params_t){
                              .dest = KEYMGR_CONTROL_DEST_SEL_VALUE_NONE,
                              .op = KEYMGR_CONTROL_OPERATION_VALUE_DISABLE,
                          });

  return kDifKeymgrLockableOk;
}

dif_keymgr_result_t dif_keymgr_get_status_codes(
    const dif_keymgr_t *keymgr, dif_keymgr_status_codes_t *status_codes) {
  if (keymgr == NULL || status_codes == NULL) {
    return kDifKeymgrBadArg;
  }

  // Read and clear OP_STATUS register (rw1c).
  uint32_t reg_op_status =
      mmio_region_read32(keymgr->params.base_addr, KEYMGR_OP_STATUS_REG_OFFSET);
  mmio_region_write32(keymgr->params.base_addr, KEYMGR_OP_STATUS_REG_OFFSET,
                      reg_op_status);

  bool is_idle = false;
  bool has_error = false;
  switch (reg_op_status) {
    case KEYMGR_OP_STATUS_STATUS_VALUE_IDLE:
      is_idle = true;
      break;
    case KEYMGR_OP_STATUS_STATUS_VALUE_DONE_SUCCESS:
      is_idle = true;
      break;
    case KEYMGR_OP_STATUS_STATUS_VALUE_DONE_ERROR:
      is_idle = true;
      has_error = true;
      break;
    case KEYMGR_OP_STATUS_STATUS_VALUE_WIP:
      break;
    default:
      return kDifKeymgrError;
  }

  // Bit 0 of `dif_keymgr_status_codes_t` indicates whether the key manager is
  // idle or not.
  *status_codes = bitfield_bit32_write(0, 0, is_idle);

  if (has_error) {
    // Read and clear ERR_CODE register (rw1c).
    uint32_t reg_err_code = mmio_region_read32(keymgr->params.base_addr,
                                               KEYMGR_ERR_CODE_REG_OFFSET);
    mmio_region_write32(keymgr->params.base_addr, KEYMGR_ERR_CODE_REG_OFFSET,
                        reg_err_code);
    // Error bits start from bit 1 in `dif_keymgr_status_codes_t`.
    // Note: The mask is hardcoded since it is not auto generated yet.
    const bitfield_field32_t kErrorBitfield = (bitfield_field32_t){
        .mask = 0xF,
        .index = 1,
    };
    if (reg_err_code > kErrorBitfield.mask || reg_err_code == 0) {
      return kDifKeymgrError;
    }
    *status_codes =
        bitfield_field32_write(*status_codes, kErrorBitfield, reg_err_code);
  }

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_get_state(const dif_keymgr_t *keymgr,
                                         dif_keymgr_state_t *state) {
  if (keymgr == NULL || state == NULL) {
    return kDifKeymgrBadArg;
  }

  uint32_t reg_state = mmio_region_read32(keymgr->params.base_addr,
                                          KEYMGR_WORKING_STATE_REG_OFFSET);

  switch (bitfield_field32_read(reg_state, KEYMGR_WORKING_STATE_STATE_FIELD)) {
    case KEYMGR_WORKING_STATE_STATE_VALUE_RESET:
      *state = kDifKeymgrStateReset;
      return kDifKeymgrOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_INIT:
      *state = kDifKeymgrStateInitialized;
      return kDifKeymgrOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_CREATOR_ROOT_KEY:
      *state = kDifKeymgrStateCreatorRootKey;
      return kDifKeymgrOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_INTERMEDIATE_KEY:
      *state = kDifKeymgrStateOwnerIntermediateKey;
      return kDifKeymgrOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_KEY:
      *state = kDifKeymgrStateOwnerRootKey;
      return kDifKeymgrOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_DISABLED:
      *state = kDifKeymgrStateDisabled;
      return kDifKeymgrOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_INVALID:
      *state = kDifKeymgrStateInvalid;
      return kDifKeymgrOk;
    default:
      return kDifKeymgrError;
  }
}

dif_keymgr_lockable_result_t dif_keymgr_generate_identity_seed(
    const dif_keymgr_t *keymgr) {
  if (keymgr == NULL) {
    return kDifKeymgrLockableBadArg;
  }

  if (!is_ready(keymgr)) {
    return kDifKeymgrLockableLocked;
  }

  start_operation(keymgr, (start_operation_params_t){
                              .dest = KEYMGR_CONTROL_DEST_SEL_VALUE_NONE,
                              .op = KEYMGR_CONTROL_OPERATION_VALUE_GENERATE_ID,
                          });

  return kDifKeymgrLockableOk;
}

dif_keymgr_lockable_result_t dif_keymgr_generate_versioned_key(
    const dif_keymgr_t *keymgr, dif_keymgr_versioned_key_params_t params) {
  if (keymgr == NULL) {
    return kDifKeymgrLockableBadArg;
  }

  start_operation_params_t hw_op_params;
  switch (params.dest) {
    case kDifKeymgrVersionedKeyDestSw:
      hw_op_params = (start_operation_params_t){
          .dest = KEYMGR_CONTROL_DEST_SEL_VALUE_NONE,
          .op = KEYMGR_CONTROL_OPERATION_VALUE_GENERATE_SW_OUTPUT,
      };
      break;
    case kDifKeymgrVersionedKeyDestAes:
      hw_op_params = (start_operation_params_t){
          .dest = KEYMGR_CONTROL_DEST_SEL_VALUE_AES,
          .op = KEYMGR_CONTROL_OPERATION_VALUE_GENERATE_HW_OUTPUT,
      };
      break;
    case kDifKeymgrVersionedKeyDestKmac:
      hw_op_params = (start_operation_params_t){
          .dest = KEYMGR_CONTROL_DEST_SEL_VALUE_KMAC,
          .op = KEYMGR_CONTROL_OPERATION_VALUE_GENERATE_HW_OUTPUT,
      };
      break;
    default:
      return kDifKeymgrLockableBadArg;
  }

  if (!is_ready(keymgr)) {
    return kDifKeymgrLockableLocked;
  }

  // Set salt and version
  mmio_region_memcpy_to_mmio32(keymgr->params.base_addr,
                               KEYMGR_SALT_0_REG_OFFSET, params.salt,
                               sizeof(params.salt));
  mmio_region_write32(keymgr->params.base_addr, KEYMGR_KEY_VERSION_REG_OFFSET,
                      params.version);

  start_operation(keymgr, hw_op_params);

  return kDifKeymgrLockableOk;
}

dif_keymgr_result_t dif_keymgr_sideload_clear_set_enabled(
    const dif_keymgr_t *keymgr, dif_keymgr_toggle_t state) {
  bool enable = false;
  if (keymgr == NULL || !toggle_to_bool(state, &enable)) {
    return kDifKeymgrBadArg;
  }

  dif_keymgr_sideload_clr_t val = state == kDifKeymgrToggleEnabled
                                      ? kDifKeyMgrSideLoadClearAll
                                      : kDifKeyMgrSideLoadClearNone;

  mmio_region_write32(keymgr->params.base_addr,
                      KEYMGR_SIDELOAD_CLEAR_REG_OFFSET, val);

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_sideload_clear_get_enabled(
    const dif_keymgr_t *keymgr, dif_keymgr_toggle_t *state) {
  if (keymgr == NULL || state == NULL) {
    return kDifKeymgrBadArg;
  }

  uint32_t reg_val = mmio_region_read32(keymgr->params.base_addr,
                                        KEYMGR_SIDELOAD_CLEAR_REG_OFFSET);
  *state = bool_to_toggle(reg_val == kDifKeyMgrSideLoadClearAll);

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_read_output(const dif_keymgr_t *keymgr,
                                           dif_keymgr_output_t *output) {
  if (keymgr == NULL || output == NULL) {
    return kDifKeymgrBadArg;
  }

  mmio_region_memcpy_from_mmio32(keymgr->params.base_addr,
                                 KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET,
                                 output->value[0], sizeof(output->value[0]));
  mmio_region_memcpy_from_mmio32(keymgr->params.base_addr,
                                 KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET,
                                 output->value[1], sizeof(output->value[1]));

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_alert_force(const dif_keymgr_t *keymgr,
                                           dif_keymgr_alert_t alert) {
  if (keymgr == NULL) {
    return kDifKeymgrBadArg;
  }

  bitfield_bit32_index_t bit_index;
  switch (alert) {
    case kDifKeymgrAlertHardware:
      bit_index = KEYMGR_ALERT_TEST_FATAL_FAULT_ERR_BIT;
      break;
    case kDifKeymgrAlertSoftware:
      bit_index = KEYMGR_ALERT_TEST_RECOV_OPERATION_ERR_BIT;
      break;
    default:
      return kDifKeymgrBadArg;
  }

  mmio_region_write32(keymgr->params.base_addr, KEYMGR_ALERT_TEST_REG_OFFSET,
                      bitfield_bit32_write(0, bit_index, true));

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_irq_is_pending(const dif_keymgr_t *keymgr,
                                              dif_keymgr_irq_t irq,
                                              bool *is_pending) {
  bitfield_bit32_index_t bit_index;
  if (keymgr == NULL || !get_irq_bit_index(irq, &bit_index) ||
      is_pending == NULL) {
    return kDifKeymgrBadArg;
  }

  uint32_t reg_val = mmio_region_read32(keymgr->params.base_addr,
                                        KEYMGR_INTR_STATE_REG_OFFSET);
  *is_pending = bitfield_bit32_read(reg_val, bit_index);

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_irq_acknowledge(const dif_keymgr_t *keymgr,
                                               dif_keymgr_irq_t irq) {
  bitfield_bit32_index_t bit_index;
  if (keymgr == NULL || !get_irq_bit_index(irq, &bit_index)) {
    return kDifKeymgrBadArg;
  }

  uint32_t reg_val = bitfield_bit32_write(0, bit_index, true);
  mmio_region_write32(keymgr->params.base_addr, KEYMGR_INTR_STATE_REG_OFFSET,
                      reg_val);

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_irq_get_enabled(const dif_keymgr_t *keymgr,
                                               dif_keymgr_irq_t irq,
                                               dif_keymgr_toggle_t *state) {
  bitfield_bit32_index_t bit_index;
  if (keymgr == NULL || !get_irq_bit_index(irq, &bit_index) || state == NULL) {
    return kDifKeymgrBadArg;
  }

  uint32_t reg_val = mmio_region_read32(keymgr->params.base_addr,
                                        KEYMGR_INTR_ENABLE_REG_OFFSET);
  *state = bool_to_toggle(bitfield_bit32_read(reg_val, bit_index));

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_irq_set_enabled(const dif_keymgr_t *keymgr,
                                               dif_keymgr_irq_t irq,
                                               dif_keymgr_toggle_t state) {
  bitfield_bit32_index_t bit_index;
  bool enable = false;
  if (keymgr == NULL || !get_irq_bit_index(irq, &bit_index) ||
      !toggle_to_bool(state, &enable)) {
    return kDifKeymgrBadArg;
  }

  uint32_t reg_val = mmio_region_read32(keymgr->params.base_addr,
                                        KEYMGR_INTR_ENABLE_REG_OFFSET);
  reg_val = bitfield_bit32_write(reg_val, bit_index, enable);
  mmio_region_write32(keymgr->params.base_addr, KEYMGR_INTR_ENABLE_REG_OFFSET,
                      reg_val);

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_irq_force(const dif_keymgr_t *keymgr,
                                         dif_keymgr_irq_t irq) {
  bitfield_bit32_index_t bit_index;
  if (keymgr == NULL || !get_irq_bit_index(irq, &bit_index)) {
    return kDifKeymgrBadArg;
  }

  uint32_t reg_val = bitfield_bit32_write(0, bit_index, true);
  mmio_region_write32(keymgr->params.base_addr, KEYMGR_INTR_TEST_REG_OFFSET,
                      reg_val);

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_irq_disable_all(
    const dif_keymgr_t *keymgr, dif_keymgr_irq_snapshot_t *snapshot) {
  if (keymgr == NULL) {
    return kDifKeymgrBadArg;
  }

  if (snapshot != NULL) {
    *snapshot = mmio_region_read32(keymgr->params.base_addr,
                                   KEYMGR_INTR_ENABLE_REG_OFFSET);
  }
  mmio_region_write32(keymgr->params.base_addr, KEYMGR_INTR_ENABLE_REG_OFFSET,
                      0);

  return kDifKeymgrOk;
}

dif_keymgr_result_t dif_keymgr_irq_restore_all(
    const dif_keymgr_t *keymgr, const dif_keymgr_irq_snapshot_t *snapshot) {
  if (keymgr == NULL || snapshot == NULL) {
    return kDifKeymgrBadArg;
  }

  mmio_region_write32(keymgr->params.base_addr, KEYMGR_INTR_ENABLE_REG_OFFSET,
                      *snapshot);

  return kDifKeymgrOk;
}
