// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_KEYMGR_H_
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_KEYMGR_H_

/**
 * @file
 * @brief <a href="/hw/ip/keymgr/doc/">Key Manager</a> Device Interface
 * Functions
 */

#include <stdint.h>

#include "sw/device/lib/base/macros.h"
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_base.h"

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

#ifdef __cplusplus
extern "C" {
#endif  // __cplusplus

/**
 * A typical usage of this library during different secure boot
 * stages is as follows:
 *
 * - In Mask ROM:
 *   - Create a new handle: `dif_keymgr_init()`.
 *   - Configure hardware: `dif_keymgr_configure()`.
 *   - Initialize state: `dif_keymgr_advance_state()`,
 *   `dif_keymgr_get_status_codes()`, `dif_keymgr_get_state()`.
 *   - Advance state: `dif_keymgr_advance_state()`,
 *     `dif_keymgr_get_status_codes()`, `dif_keymgr_get_state()`.
 * - In subsequent boot stages, i.e. ROM_EXT, BL0, kernel:
 *   - Create a new handle: `dif_keymgr_init()`.
 *   - Generate keys and/or identity seeds:
 *     `dif_keymgr_generate_versioned_key()`,
 *     `dif_keymgr_generate_identity_seed()`, `dif_keymgr_get_status_codes()`.
 *   - Read output (if applicable): `dif_keymgr_read_output()`.
 *   - Advance state: `dif_keymgr_advance_state()`,
 *     `dif_keymgr_get_status_codes()`, `dif_keymgr_get_state()`.
 */

/**
 * Enumeration for side load slot clearing.
 */
typedef enum dif_keymgr_sideload_clr {
  kDifKeyMgrSideLoadClearNone,
  kDifKeyMgrSideLoadClearAes,
  kDifKeyMgrSideLoadClearHmac,
  kDifKeyMgrSideLoadClearKmac,
  kDifKeyMgrSideLoadClearOtbn,
  kDifKeyMgrSideLoadClearAll,
} dif_keymgr_sideload_clr_t;

/**
 * Runtime configuration for key manager.
 *
 * This struct describes runtime information for one-time configuration of the
 * hardware.
 */
typedef struct dif_keymgr_config {
  /**
   * Number of key manager cycles before the entropy is reseeded.
   *
   * Key manager uses random values generated by the entropy source for
   * initializing its state and clearing sideload keys. This value determines
   * the frequency at which this random value is updated.
   */
  uint16_t entropy_reseed_interval;
} dif_keymgr_config_t;

/**
 * Key manager states.
 *
 * Key manager has seven states that control its operation. During secure boot,
 * key manager transitions between these states sequentially and these
 * transitions are irreversible until a power cycle.
 *
 * The secret value of key manager changes at each state transition in a
 * well-defined manner, thus its meaning is tied to the current state of key
 * manager.
 *
 * The functionality of key manager is directly tied to the life cycle
 * controller peripheral and it is explicitly disabled during specific life
 * cycle stages. If key manager has not been initialized, it cannot be
 * initialized until it is enabled by life cycle controller. If key manager is
 * disabled by life cycle controller while it is in an operational state, it
 * immediately wipes its contents and transitions to Disabled state.
 */
typedef enum dif_keymgr_state {
  /**
   * Reset state.
   *
   * This is the initial state of key manager after PoR. At this state, the
   * secret value of key manager is non-deterministic, i.e. some value based on
   * the physical characteristics of the device and environment conditions.
   */
  kDifKeymgrStateReset,
  /**
   * Initialized state.
   *
   * Secret value of key manager is initialized with random values generated by
   * the entropy source. This is not an operational state and the key manager
   * state must be advanced one more time before keys or identity seeds can be
   * generated.
   */
  kDifKeymgrStateInitialized,
  /**
   * CreatorRootKey state.
   *
   * This is the first operational state of key manager. At this state, key
   * manager can generate a versioned creator key or a creator identity seed
   * that can be used to generate a creator identity using an asymmetric KDF.
   */
  kDifKeymgrStateCreatorRootKey,
  /**
   * OwnerIntermediateKey state.
   *
   * This is the second operational state of key manager. At this state, key
   * manager can generate a versioned intermediate owner key or an intermediate
   * owner identity seed that can be used to generate an intermediate owner
   * identity using an asymmetric KDF.
   */
  kDifKeymgrStateOwnerIntermediateKey,
  /**
   * OwnerRootKey state.
   *
   * This is the last operational state of key manager. At this state, key
   * manager can generate a versioned owner key or an owner identity seed that
   * can be used to generate an owner identity using an asymmetric KDF.
   */
  kDifKeymgrStateOwnerRootKey,
  /**
   * Disabled state.
   *
   * This is a terminal state where key manager is no longer operational. At
   * this state, the secret value of key manager is a random value.
   */
  kDifKeymgrStateDisabled,
  /**
   * Invalid state.
   *
   * Keymgr is in an invalid state and must be reset.
   */
  kDifKeymgrStateInvalid,
} dif_keymgr_state_t;

/**
 * Configures key manager with runtime information.
 *
 * This function should need to be called once for the lifetime of `keymgr`.
 *
 * @param keymgr A key manager handle.
 * @param config Runtime configuration parameters.
 * @return The result of the operation.
 */
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_configure(const dif_keymgr_t *keymgr,
                                  dif_keymgr_config_t config);

/**
 * Parameters for a key manager state.
 */
typedef struct dif_keymgr_state_params {
  /**
   * This value is used by key manager to derive secret values and can be either
   * a value that represents the contents of a boot stage, e.g. a (truncated)
   * hash, or a tag.
   *
   * If it is a hash, changes in a boot stage will change the secret value, and
   * consequently the versioned keys and identity seeds generated at subsequent
   * boot stages. If it is a tag, those secret values, versioned keys, and
   * identity seeds will be preserved across updates of the boot stage as long
   * as the tag remains the same.
   */
  uint32_t binding_value[8];

  /**
   * Maximum allowed version for keys generated at a state.
   */
  uint32_t max_key_version;
} dif_keymgr_state_params_t;

/**
 * Advances key manager state.
 *
 * This function instructs key manager to transition to the next state, i.e.
 * Reset -> Initialized -> CreatorRootKey -> OwnerIntermediateKey ->
 * OwnerRootKey -> Disabled. Once a state transition starts, key manager locks
 * the control register until the transition is complete. State transitions are
 * irreversible until a power cycle.
 *
 * The entropy source must be initialized before this function is called. After
 * PoR, key manager is in Reset state with a non-deterministic secret value. The
 * first call to this function after PoR causes key manager to initialize its
 * secret value using the random values generated by the entropy source and
 * transition to Initialized state.
 *
 * `params` is required when the next state is an operational state,
 * i.e. `CreatorRootKey`, `OwnerIntermediateKey`, or `OwnerRootKey`. It must be
 * `NULL` for all other cases.
 *
 * This is an asynchronous function because key manager state transitions
 * involve KMAC operations that can take some time to complete. Clients must
 * check the status of key manager using `dif_keymgr_get_status_codes()` before
 * calling other functions in this library.
 *
 * @param keymgr A key manager handle.
 * @param params The binding and max key version value for the next state.
 * @return The result of the operation.
 */
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_advance_state(const dif_keymgr_t *keymgr,
                                      const dif_keymgr_state_params_t *params);

/**
 * Disables key manager.
 *
 * This function disables key manager until the next power cycle by making it
 * transition to Disabled state. Disabled state is a terminal state where key
 * manager is no longer operational and its secret value is a random value.
 *
 * @param keymgr A key manager handle.
 * @return The result of the operation.
 */
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_disable(const dif_keymgr_t *keymgr);

/**
 * Status code bit flags.
 *
 * See also: `dif_keymgr_status_codes_t`.
 */
typedef enum dif_keymgr_status_code {
  /**
   * Key manager is idle.
   */
  kDifKeymgrStatusCodeIdle = 1 << 0,
  /**
   * Software invoked an invalid operation.
   */
  kDifKeymgrStatusCodeInvalidOperation = 1 << 1,
  /**
   * Key manager issued invalid data to KMAC interface.
   */
  kDifKeymgrStatusCodeInvalidKmacInput = 1 << 2,
  /**
   * Software performed an invalid shadow update.
   */
  kDifKeymgrStatusCodeInvalidKmacOutput = 1 << 3,
  /**
   * Key manager encountered invalid state
   */
  kDifKeymgrStatusCodeInvalidState = 1 << 4,

} dif_keymgr_status_code_t;

/**
 * A bit vector of status codes.
 *
 * The following snippet can be used to check if key manager is idle:
 *
 *   bool is_idle = (status_codes & kDifKeymgrStatusCodeIdle);
 *
 * The following snippet can be used to check if key manager is idle and
 * error-free:
 *
 *   bool is_idle_and_ok = (status_codes == kDifKeymgrStatusCodeIdle);
 *
 * See also: `dif_keymgr_status_code_t`.
 */
typedef uint8_t dif_keymgr_status_codes_t;

/**
 * Gets the operational status of key manager.
 *
 * This function also clears OP_STATUS and ERR_CODE registers after reading
 * them.
 *
 * @param keymgr A key manager handle.
 * @param[out] status_codes Out-param for key manager status codes.
 * @return The result of the operation.
 */
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_get_status_codes(
    const dif_keymgr_t *keymgr, dif_keymgr_status_codes_t *status_codes);

/**
 * Gets the current state of key manager.
 *
 * @param keymgr A key manager handle.
 * @param[out] state Out-param for current key manager state.
 * @return The result of the operation.
 */
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_get_state(const dif_keymgr_t *keymgr,
                                  dif_keymgr_state_t *state);

/**
 * Generates an identity seed.
 *
 * This function requests key manager to generate an identity seed using its
 * current secret value. Clients must first verify that the operation was
 * successful using `dif_keymgr_get_status_codes()` before reading the generated
 * identity seed using `dif_keymgr_read_output()`.
 *
 * The generated seed can be used to generate an identity using an asymmetric
 * KDF.
 *
 * @param keymgr A key manager handle.
 * @return The result of the operation.
 */
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_generate_identity_seed(const dif_keymgr_t *keymgr);

/**
 * Destination of a versioned key generation operation.
 *
 * Key manager can make the output of a versioned key generation operation
 * available to software or sideload it directly to a peripheral device. When
 * the destination is a peripheral device, the output of the operation is not
 * visible to software and a different derivation constant is used for each
 * peripheral.
 */
typedef enum dif_keymgr_versioned_key_dest {
  /**
   * Store the generated versioned key in software visible registers.
   *
   * The generated versioned key can be read by calling
   * `dif_keymgr_read_output()` after verifying that the operation was
   * successful using `dif_keymgr_get_status_codes()`.
   */
  kDifKeymgrVersionedKeyDestSw,
  /**
   * Sideload the generated versioned key to AES device.
   */
  kDifKeymgrVersionedKeyDestAes,
  /**
   * Sideload the generated versioned key to KMAC device.
   */
  kDifKeymgrVersionedKeyDestKmac,
  /**
   * Sideload the generated versioned key to Otbn device.
   */
  kDifKeymgrVersionedKeyDestOtbn,
  /**
   * \internal Last key destination.
   */
  kDifKeymgrVersionedKeyDestLast = kDifKeymgrVersionedKeyDestOtbn,
} dif_keymgr_versioned_key_dest_t;

/**
 * Parameters for generating a versioned key.
 */
typedef struct dif_keymgr_versioned_key_params {
  /**
   * Destination of the generated versioned key.
   *
   * See also: `dif_keymgr_versioned_key_dest_t`.
   */
  dif_keymgr_versioned_key_dest_t dest;
  /**
   * Salt value to use for key generation.
   */
  uint32_t salt[8];
  /**
   * Version value to use for key generation.
   */
  uint32_t version;
} dif_keymgr_versioned_key_params_t;

/**
 * Generates a versioned key.
 *
 * This function requests key manager to generate a versioned key using its
 * current secret value and the provided parameters. The generated key can be
 * sideloaded directly to a peripheral device or made visible to software using
 * `params.dest`. If the destination is software, clients must first verify that
 * the operation was successful using `dif_keymgr_get_status_codes()` before
 * reading the generated key using `dif_keymgr_read_output()`.
 *
 * @param keymgr A key manager handle.
 * @param params Key generation parameters.
 * @return The result of the operation.
 */
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_generate_versioned_key(
    const dif_keymgr_t *keymgr, dif_keymgr_versioned_key_params_t params);

/**
 * Starts or stops clearing of sideload keys.
 *
 * When a key is generated to be sideloaded to a hardware peripheral, key
 * manager stores it in a set of storage registers. Calling this function with
 * `state` set to `kDifKeymgrToggleEnabled` causes key manager to clear sideload
 * keys continously using random values from the entropty source. Callers must
 * disable clearing of sideload keys to resume normal sideload operation.
 *
 * @param keymgr A key manager handle.
 * @param state The new toggle state for sideload clear.
 * @return The result of the operation.
 */
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_sideload_clear_set_enabled(const dif_keymgr_t *keymgr,
                                                   dif_toggle_t state);

/**
 * Checks whether clearing of sideload keys is enabled or not.
 *
 * @param keymgr A key manager handle.
 * @param[out] Out-param for the current toggle state of sideload clear.
 * @return The result of the operation.
 */
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_sideload_clear_get_enabled(const dif_keymgr_t *keymgr,
                                                   dif_toggle_t *state);

/**
 * Output of a key manager operation.
 *
 * Key manager outputs are in two-shares.
 */
typedef struct dif_keymgr_output {
  uint32_t value[2][8];
} dif_keymgr_output_t;

/**
 * Reads the output of the last key manager operation.
 *
 * After starting a key manager operation, clients must verify that the
 * operation was successful using `dif_keymgr_get_status_codes()` before calling
 * this function.
 *
 * When key manager is used for versioned key generation, the output of this
 * function is valid only if the destination of the operation was
 * `kDifKeymgrVersionedKeyDestSw`.
 *
 * See also: `dif_keymgr_output_t`.
 *
 * @param keymgr A key manager handle.
 * @param[out] output Out-param for key manager output.
 * @return The result of the operation.
 */
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_read_output(const dif_keymgr_t *keymgr,
                                    dif_keymgr_output_t *output);

#ifdef __cplusplus
}  // extern "C"
#endif  // __cplusplus

#endif  // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_KEYMGR_H_
