/* _NVRM_COPYRIGHT_BEGIN_
 *
 * Copyright 2021 by NVIDIA Corporation.  All rights reserved.  All
 * information contained herein is proprietary and confidential to NVIDIA
 * Corporation.  Any use, reproduction, or disclosure without the written
 * permission of NVIDIA Corporation is prohibited.
 *
 * _NVRM_COPYRIGHT_END_
 */
#ifndef LIBNVRISCV_SSP_H
#define LIBNVRISCV_SSP_H
#include <stdint.h>
#include <misc/gcc_attrs.h>
#include <error/common-errors.h>

#if NVRISCV_FEATURE_SSP_FORCE_SW_CANARY
static inline error_t ssp_generate_and_set_canary_with_init(void) GCC_ATTR_WARN_UNUSED;
static inline error_t ssp_generate_and_set_canary_with_init(void)
{
    return E_NOTSUPPORTED;
}

static inline error_t ssp_generate_and_set_canary(void) GCC_ATTR_WARN_UNUSED;
static inline error_t ssp_generate_and_set_canary(void)
{
    return E_NOTSUPPORTED;
}
#else // NVRISCV_FEATURE_SSP_FORCE_SW_CANARY
/*!
 * \brief Initializes HWRNG, generates and sets stack canary.
 * \return
 *      NVRV_OK                success, canary is set
 *      NVRV_ERR_NOT_SUPPORTED if SCP driver is not enabled
 *      Other                  passed-through SCP errors
 *
 * This function:
 * - Initializes HWRNG inside SCP (via SCP driver)
 * - Generates and sets random with ssp_generate_and_set_canary()
 * - Shuts down HWRNG
 *
 * \warning It should be called early at the start of module.
 * \warning It should not be used, if module is using SCP for other purposes -
 * in that case module should take care of SCP and just call ssp_generate_and_set_canary()
 * \note Errors reported by this function should be considered fatal.
 */
error_t ssp_generate_and_set_canary_with_init(void) GCC_ATTR_WARN_UNUSED;

/*!
 * \brief Generates and sets stack canary.
 * \return
 *      NVRV_OK                success, canary is set
 *      NVRV_ERR_NOT_SUPPORTED if SCP driver is not enabled
 *      Other                  passed-through SCP errors
 *
 * This function generates random number using SCP HWRNG, then writes it to
 * canary.
 *
 * \warning There are requirements regarding symbols used by this function when
 * used.
 * \warning This function assumes SSP is initialized and running.
 * \note Errors reported by this function should be considered fatal.
 */
error_t ssp_generate_and_set_canary(void) GCC_ATTR_WARN_UNUSED;
#endif // NVRISCV_FEATURE_SSP_FORCE_SW_CANARY

/*!
 * \brief Returns current canary value.
 * \return canary value
 *
 * This function shuld be used to retrieve canary value for storage during
 * partition or context switches (if canary can't be regenerated).
 */
uintptr_t ssp_get_canary(void);

/*!
 * \brief Sets current canary value.
 * \param[in] canary
 *
 * This function should be used to:
 * - Restore stack canary after partition or context switches
 * - Configure canary if SCP is not used or not available.
 */
void ssp_set_canary(uintptr_t canary);

#if NVRISCV_FEATURE_SSP_ENABLE_FAIL_HOOK
/*!
 * \brief Hook called if canary fails.
 *
 * \warning This hook shuold be (most likely) implemented in assembly and make
 * sure stack is not used (as stack pointer is not reliable when this function
 * is reached).
 * \warning This hook should not return.
 */
extern void ssp_check_fail_hook(void) GCC_ATTR_NORETURN;
#endif // NVRISCV_FEATURE_SSP_ENABLE_FAIL_HOOK

#endif // LIBNVRISCV_SSP_H
