// 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(kDifKeymgrStatusCodeInvalidKmacCommand >> 1 ==
                  1 << KEYMGR_ERR_CODE_INVALID_STATES_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.");
static_assert(kDifKeymgrStatusCodeInvalidKmacOutput >> 1 ==
                  1 << KEYMGR_ERR_CODE_INVALID_KMAC_DATA_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.
 */
DIF_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.
 */
DIF_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.
 */
DIF_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`.
 */
DIF_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;
}
