// 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_
