// 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 "sw/device/lib/dif/dif_base.h"

#include "keymgr_regs.h"  // Generated.
#include "sw/device/lib/dif/autogen/dif_keymgr_autogen.h"

/**
 * 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.");
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.");
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->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->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_SHADOWED_DEST_SEL_FIELD, params.dest);
  reg_control = bitfield_field32_write(
      reg_control, KEYMGR_CONTROL_SHADOWED_OPERATION_FIELD, params.op);
  mmio_region_write32_shadowed(keymgr->base_addr,
                               KEYMGR_CONTROL_SHADOWED_REG_OFFSET, reg_control);
  mmio_region_write32(keymgr->base_addr, KEYMGR_START_REG_OFFSET,
                      1 << KEYMGR_START_EN_BIT);
}

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

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

  return kDifOk;
}

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

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

  // 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->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 kDifError;
  }

  // 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 kDifBadArg;
    }

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

    // Check if MAX_*_KEY_VER register is locked.
    uint32_t reg_max_key_ver_wen = mmio_region_read32(
        keymgr->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 kDifLocked;
    }

    // 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->base_addr, KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET,
        params->binding_value, sizeof(params->binding_value));
    mmio_region_write32(keymgr->base_addr, KEYMGR_SW_BINDING_REGWEN_REG_OFFSET,
                        0);

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

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

  return kDifOk;
}

dif_result_t dif_keymgr_disable(const dif_keymgr_t *keymgr) {
  if (keymgr == NULL) {
    return kDifBadArg;
  }

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

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

  return kDifOk;
}

dif_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 kDifBadArg;
  }

  // Read and clear OP_STATUS register (rw1c).
  uint32_t reg_op_status =
      mmio_region_read32(keymgr->base_addr, KEYMGR_OP_STATUS_REG_OFFSET);
  mmio_region_write32(keymgr->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 kDifError;
  }

  // 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->base_addr, KEYMGR_ERR_CODE_REG_OFFSET);
    mmio_region_write32(keymgr->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 kDifError;
    }
    *status_codes =
        bitfield_field32_write(*status_codes, kErrorBitfield, reg_err_code);
  }

  return kDifOk;
}

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

  uint32_t reg_state =
      mmio_region_read32(keymgr->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 kDifOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_INIT:
      *state = kDifKeymgrStateInitialized;
      return kDifOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_CREATOR_ROOT_KEY:
      *state = kDifKeymgrStateCreatorRootKey;
      return kDifOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_INTERMEDIATE_KEY:
      *state = kDifKeymgrStateOwnerIntermediateKey;
      return kDifOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_KEY:
      *state = kDifKeymgrStateOwnerRootKey;
      return kDifOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_DISABLED:
      *state = kDifKeymgrStateDisabled;
      return kDifOk;
    case KEYMGR_WORKING_STATE_STATE_VALUE_INVALID:
      *state = kDifKeymgrStateInvalid;
      return kDifOk;
    default:
      return kDifError;
  }
}

dif_result_t dif_keymgr_generate_identity_seed(const dif_keymgr_t *keymgr) {
  if (keymgr == NULL) {
    return kDifBadArg;
  }

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

  start_operation(keymgr,
                  (start_operation_params_t){
                      .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
                      .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_ID,
                  });

  return kDifOk;
}

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

  start_operation_params_t hw_op_params;
  switch (params.dest) {
    case kDifKeymgrVersionedKeyDestSw:
      hw_op_params = (start_operation_params_t){
          .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
          .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_SW_OUTPUT,
      };
      break;
    case kDifKeymgrVersionedKeyDestAes:
      hw_op_params = (start_operation_params_t){
          .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_AES,
          .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
      };
      break;
    case kDifKeymgrVersionedKeyDestKmac:
      hw_op_params = (start_operation_params_t){
          .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_KMAC,
          .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
      };
      break;
    case kDifKeymgrVersionedKeyDestOtbn:
      hw_op_params = (start_operation_params_t){
          .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_OTBN,
          .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
      };
      break;
    default:
      return kDifBadArg;
  }

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

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

  start_operation(keymgr, hw_op_params);

  return kDifOk;
}

dif_result_t dif_keymgr_sideload_clear_set_enabled(const dif_keymgr_t *keymgr,
                                                   dif_toggle_t state) {
  if (keymgr == NULL || !dif_is_valid_toggle(state)) {
    return kDifBadArg;
  }

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

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

  return kDifOk;
}

dif_result_t dif_keymgr_sideload_clear_get_enabled(const dif_keymgr_t *keymgr,
                                                   dif_toggle_t *state) {
  if (keymgr == NULL || state == NULL) {
    return kDifBadArg;
  }

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

  return kDifOk;
}

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

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

  return kDifOk;
}
