/*
 * Copyright (c) 2016 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Crypto Cipher APIs
 *
 * This file contains the Crypto Abstraction layer APIs.
 *
 * [Experimental] Users should note that the APIs can change
 * as a part of ongoing development.
 */

#ifndef ZEPHYR_INCLUDE_CRYPTO_H_
#define ZEPHYR_INCLUDE_CRYPTO_H_

#include <device.h>
#include <errno.h>
#include <sys/util.h>
#include <sys/__assert.h>
#include <crypto/hash.h>
#include "cipher.h"

/**
 * @brief Crypto APIs
 * @defgroup crypto Crypto
 * @{
 */


/* ctx.flags values. Not all drivers support all flags.
 * A user app can query the supported hw / driver
 * capabilities via provided API (crypto_query_hwcaps()), and choose a
 * supported config during the session setup.
 */
#define CAP_OPAQUE_KEY_HNDL		BIT(0)
#define CAP_RAW_KEY			BIT(1)

/* TBD to define */
#define CAP_KEY_LOADING_API		BIT(2)

/** Whether the output is placed in separate buffer or not */
#define CAP_INPLACE_OPS			BIT(3)
#define CAP_SEPARATE_IO_BUFS		BIT(4)

/**
 * These denotes if the output (completion of a cipher_xxx_op) is conveyed
 * by the op function returning, or it is conveyed by an async notification
 */
#define CAP_SYNC_OPS			BIT(5)
#define CAP_ASYNC_OPS			BIT(6)

/** Whether the hardware/driver supports autononce feature */
#define CAP_AUTONONCE			BIT(7)

/** Don't prefix IV to cipher blocks */
#define CAP_NO_IV_PREFIX		BIT(8)

/* More flags to be added as necessary */

/** @brief Crypto driver API definition. */
__subsystem struct crypto_driver_api {
	int (*query_hw_caps)(const struct device *dev);

	/* Setup a crypto session */
	int (*cipher_begin_session)(const struct device *dev, struct cipher_ctx *ctx,
			     enum cipher_algo algo, enum cipher_mode mode,
			     enum cipher_op op_type);

	/* Tear down an established session */
	int (*cipher_free_session)(const struct device *dev, struct cipher_ctx *ctx);

	/* Register async crypto op completion callback with the driver */
	int (*cipher_async_callback_set)(const struct device *dev,
					 cipher_completion_cb cb);

	/* Setup a hash session */
	int (*hash_begin_session)(const struct device *dev, struct hash_ctx *ctx,
				  enum hash_algo algo);
	/* Tear down an established hash session */
	int (*hash_free_session)(const struct device *dev, struct hash_ctx *ctx);
	/* Register async hash op completion callback with the driver */
	int (*hash_async_callback_set)(const struct device *dev,
					 hash_completion_cb cb);
};

/* Following are the public API a user app may call.
 * The first two relate to crypto "session" setup / teardown. Further we
 * have four cipher mode specific (CTR, CCM, CBC ...) calls to perform the
 * actual crypto operation in the context of a session. Also we have an
 * API to provide the callback for async operations.
 */

/**
 * @brief Query the crypto hardware capabilities
 *
 * This API is used by the app to query the capabilities supported by the
 * crypto device. Based on this the app can specify a subset of the supported
 * options to be honored for a session during cipher_begin_session().
 *
 * @param dev Pointer to the device structure for the driver instance.
 *
 * @return bitmask of supported options.
 */
static inline int crypto_query_hwcaps(const struct device *dev)
{
	struct crypto_driver_api *api;
	int tmp;

	api = (struct crypto_driver_api *) dev->api;

	tmp = api->query_hw_caps(dev);

	__ASSERT((tmp & (CAP_OPAQUE_KEY_HNDL | CAP_RAW_KEY)) != 0,
		 "Driver should support at least one key type: RAW/Opaque");

	__ASSERT((tmp & (CAP_INPLACE_OPS | CAP_SEPARATE_IO_BUFS)) != 0,
	     "Driver should support at least one IO buf type: Inplace/separate");

	__ASSERT((tmp & (CAP_SYNC_OPS | CAP_ASYNC_OPS)) != 0,
		"Driver should support at least one op-type: sync/async");
	return tmp;

}

/**
 * @}
 */

/**
 * @brief Crypto Cipher APIs
 * @defgroup crypto_cipher Cipher
 * @ingroup crypto
 * @{
 */

/**
 * @brief Setup a crypto session
 *
 * Initializes one time parameters, like the session key, algorithm and cipher
 * mode which may remain constant for all operations in the session. The state
 * may be cached in hardware and/or driver data state variables.
 *
 * @param  dev      Pointer to the device structure for the driver instance.
 * @param  ctx      Pointer to the context structure. Various one time
 *			parameters like key, keylength, etc. are supplied via
 *			this structure. The structure documentation specifies
 *			which fields are to be populated by the app before
 *			making this call.
 * @param  algo     The crypto algorithm to be used in this session. e.g AES
 * @param  mode     The cipher mode to be used in this session. e.g CBC, CTR
 * @param  optype   Whether we should encrypt or decrypt in this session
 *
 * @return 0 on success, negative errno code on fail.
 */
static inline int cipher_begin_session(const struct device *dev,
				       struct cipher_ctx *ctx,
				       enum cipher_algo algo,
				       enum cipher_mode  mode,
				       enum cipher_op optype)
{
	struct crypto_driver_api *api;
	uint32_t flags;

	api = (struct crypto_driver_api *) dev->api;
	ctx->device = dev;
	ctx->ops.cipher_mode = mode;

	flags = (ctx->flags & (CAP_OPAQUE_KEY_HNDL | CAP_RAW_KEY));
	__ASSERT(flags != 0U, "Keytype missing: RAW Key or OPAQUE handle");
	__ASSERT(flags != (CAP_OPAQUE_KEY_HNDL | CAP_RAW_KEY),
			 "conflicting options for keytype");

	flags = (ctx->flags & (CAP_INPLACE_OPS | CAP_SEPARATE_IO_BUFS));
	__ASSERT(flags != 0U, "IO buffer type missing");
	__ASSERT(flags != (CAP_INPLACE_OPS | CAP_SEPARATE_IO_BUFS),
			"conflicting options for IO buffer type");

	flags = (ctx->flags & (CAP_SYNC_OPS | CAP_ASYNC_OPS));
	__ASSERT(flags != 0U, "sync/async type missing");
	__ASSERT(flags != (CAP_SYNC_OPS |  CAP_ASYNC_OPS),
			"conflicting options for sync/async");

	return api->cipher_begin_session(dev, ctx, algo, mode, optype);
}

/**
 * @brief Cleanup a crypto session
 *
 * Clears the hardware and/or driver state of a previous session.
 *
 * @param  dev      Pointer to the device structure for the driver instance.
 * @param  ctx      Pointer to the crypto context structure of the session
 *			to be freed.
 *
 * @return 0 on success, negative errno code on fail.
 */
static inline int cipher_free_session(const struct device *dev,
				      struct cipher_ctx *ctx)
{
	struct crypto_driver_api *api;

	api = (struct crypto_driver_api *) dev->api;

	return api->cipher_free_session(dev, ctx);
}

/**
 * @brief Registers an async crypto op completion callback with the driver
 *
 * The application can register an async crypto op completion callback handler
 * to be invoked by the driver, on completion of a prior request submitted via
 * cipher_do_op(). Based on crypto device hardware semantics, this is likely to
 * be invoked from an ISR context.
 *
 * @param  dev   Pointer to the device structure for the driver instance.
 * @param  cb    Pointer to application callback to be called by the driver.
 *
 * @return 0 on success, -ENOTSUP if the driver does not support async op,
 *			  negative errno code on other error.
 */
static inline int cipher_callback_set(const struct device *dev,
				      cipher_completion_cb cb)
{
	struct crypto_driver_api *api;

	api = (struct crypto_driver_api *) dev->api;

	if (api->cipher_async_callback_set) {
		return api->cipher_async_callback_set(dev, cb);
	}

	return -ENOTSUP;

}

/**
 * @brief Perform single-block crypto operation (ECB cipher mode). This
 * should not be overloaded to operate on multiple blocks for security reasons.
 *
 * @param  ctx       Pointer to the crypto context of this op.
 * @param  pkt   Structure holding the input/output buffer pointers.
 *
 * @return 0 on success, negative errno code on fail.
 */
static inline int cipher_block_op(struct cipher_ctx *ctx,
				     struct cipher_pkt *pkt)
{
	__ASSERT(ctx->ops.cipher_mode == CRYPTO_CIPHER_MODE_ECB, "ECB mode "
		 "session invoking a different mode handler");

	pkt->ctx = ctx;
	return ctx->ops.block_crypt_hndlr(ctx, pkt);
}

/**
 * @brief Perform Cipher Block Chaining (CBC) crypto operation.
 *
 * @param  ctx       Pointer to the crypto context of this op.
 * @param  pkt   Structure holding the input/output buffer pointers.
 * @param  iv        Initialization Vector (IV) for the operation. Same
 *			 IV value should not be reused across multiple
 *			 operations (within a session context) for security.
 *
 * @return 0 on success, negative errno code on fail.
 */
static inline int cipher_cbc_op(struct cipher_ctx *ctx,
				struct cipher_pkt *pkt, uint8_t *iv)
{
	__ASSERT(ctx->ops.cipher_mode == CRYPTO_CIPHER_MODE_CBC, "CBC mode "
		 "session invoking a different mode handler");

	pkt->ctx = ctx;
	return ctx->ops.cbc_crypt_hndlr(ctx, pkt, iv);
}

/**
 * @brief Perform Counter (CTR) mode crypto operation.
 *
 * @param  ctx       Pointer to the crypto context of this op.
 * @param  pkt   Structure holding the input/output buffer pointers.
 * @param  iv        Initialization Vector (IV) for the operation. We use a
 *			 split counter formed by appending IV and ctr.
 *			 Consequently  ivlen = keylen - ctrlen. 'ctrlen' is
 *			 specified during session setup through the
 *			 'ctx.mode_params.ctr_params.ctr_len' parameter. IV
 *			 should not be reused across multiple operations
 *			 (within a session context) for security. The non-IV
 *			 part of the split counter is transparent to the caller
 *			 and is fully managed by the crypto provider.
 *
 * @return 0 on success, negative errno code on fail.
 */
static inline int cipher_ctr_op(struct cipher_ctx *ctx,
				struct cipher_pkt *pkt, uint8_t *iv)
{
	__ASSERT(ctx->ops.cipher_mode == CRYPTO_CIPHER_MODE_CTR, "CTR mode "
		 "session invoking a different mode handler");

	pkt->ctx = ctx;
	return ctx->ops.ctr_crypt_hndlr(ctx, pkt, iv);
}

/**
 * @brief Perform Counter with CBC-MAC (CCM) mode crypto operation
 *
 * @param  ctx       Pointer to the crypto context of this op.
 * @param  pkt   Structure holding the input/output, Associated
 *			 Data (AD) and auth tag buffer pointers.
 * @param  nonce     Nonce for the operation. Same nonce value should not
 *			 be reused across multiple operations (within a
 *			 session context) for security.
 *
 * @return 0 on success, negative errno code on fail.
 */
static inline int cipher_ccm_op(struct cipher_ctx *ctx,
				struct cipher_aead_pkt *pkt, uint8_t *nonce)
{
	__ASSERT(ctx->ops.cipher_mode == CRYPTO_CIPHER_MODE_CCM, "CCM mode "
		 "session invoking a different mode handler");

	pkt->pkt->ctx = ctx;
	return ctx->ops.ccm_crypt_hndlr(ctx, pkt, nonce);
}

/**
 * @brief Perform Galois/Counter Mode (GCM) crypto operation
 *
 * @param  ctx       Pointer to the crypto context of this op.
 * @param  pkt   Structure holding the input/output, Associated
 *			 Data (AD) and auth tag buffer pointers.
 * @param  nonce     Nonce for the operation. Same nonce value should not
 *			 be reused across multiple operations (within a
 *			 session context) for security.
 *
 * @return 0 on success, negative errno code on fail.
 */
static inline int cipher_gcm_op(struct cipher_ctx *ctx,
				struct cipher_aead_pkt *pkt, uint8_t *nonce)
{
	__ASSERT(ctx->ops.cipher_mode == CRYPTO_CIPHER_MODE_GCM, "GCM mode "
		 "session invoking a different mode handler");

	pkt->pkt->ctx = ctx;
	return ctx->ops.gcm_crypt_hndlr(ctx, pkt, nonce);
}


/**
 * @}
 */

/**
 * @brief Crypto Hash APIs
 * @defgroup crypto_hash Hash
 * @ingroup crypto
 * @{
 */


/**
 * @brief Setup a hash session
 *
 * Initializes one time parameters, like the algorithm which may
 * remain constant for all operations in the session. The state may be
 * cached in hardware and/or driver data state variables.
 *
 * @param  dev      Pointer to the device structure for the driver instance.
 * @param  ctx      Pointer to the context structure. Various one time
 *			parameters like session capabilities and algorithm are
 *			supplied via this structure. The structure documentation
 *			specifies which fields are to be populated by the app
 *			before making this call.
 * @param  algo     The hash algorithm to be used in this session. e.g sha256
 *
 * @return 0 on success, negative errno code on fail.
 */
static inline int hash_begin_session(const struct device *dev,
				     struct hash_ctx *ctx,
				     enum hash_algo algo)
{
	uint32_t flags;
	struct crypto_driver_api *api;

	api = (struct crypto_driver_api *) dev->api;
	ctx->device = dev;
	ctx->device = dev;

	flags = (ctx->flags & (CAP_INPLACE_OPS | CAP_SEPARATE_IO_BUFS));
	__ASSERT(flags != 0U, "IO buffer type missing");
	__ASSERT(flags != (CAP_INPLACE_OPS | CAP_SEPARATE_IO_BUFS),
			"conflicting options for IO buffer type");

	flags = (ctx->flags & (CAP_SYNC_OPS | CAP_ASYNC_OPS));
	__ASSERT(flags != 0U, "sync/async type missing");
	__ASSERT(flags != (CAP_SYNC_OPS |  CAP_ASYNC_OPS),
			"conflicting options for sync/async");


	return api->hash_begin_session(dev, ctx, algo);
}

/**
 * @brief Cleanup a hash session
 *
 * Clears the hardware and/or driver state of a session. @see hash_begin_session
 *
 * @param  dev      Pointer to the device structure for the driver instance.
 * @param  ctx      Pointer to the crypto hash  context structure of the session
 *		    to be freed.
 *
 * @return 0 on success, negative errno code on fail.
 */
static inline int hash_free_session(const struct device *dev,
				    struct hash_ctx *ctx)
{
	struct crypto_driver_api *api;

	api = (struct crypto_driver_api *) dev->api;

	return api->hash_free_session(dev, ctx);
}

/**
 * @brief Registers an async hash completion callback with the driver
 *
 * The application can register an async hash completion callback handler
 * to be invoked by the driver, on completion of a prior request submitted via
 * hash_compute(). Based on crypto device hardware semantics, this is likely to
 * be invoked from an ISR context.
 *
 * @param  dev   Pointer to the device structure for the driver instance.
 * @param  cb    Pointer to application callback to be called by the driver.
 *
 * @return 0 on success, -ENOTSUP if the driver does not support async op,
 *			  negative errno code on other error.
 */
static inline int hash_callback_set(const struct device *dev,
				    hash_completion_cb cb)
{
	struct crypto_driver_api *api;

	api = (struct crypto_driver_api *) dev->api;

	if (api->hash_async_callback_set) {
		return api->hash_async_callback_set(dev, cb);
	}

	return -ENOTSUP;

}

/**
 * @brief Perform  a cryptographic hash function.
 *
 * @param  ctx       Pointer to the hash context of this op.
 * @param  pkt       Structure holding the input/output.

 * @return 0 on success, negative errno code on fail.
 */
static inline int hash_compute(struct hash_ctx *ctx, struct hash_pkt *pkt)
{
	pkt->ctx = ctx;

	return ctx->hash_hndlr(ctx, pkt, true);
}

/**
 * @brief Perform  a cryptographic multipart hash operation.
 *
 * This function can be called zero or more times, passing a slice of the
 * the data. The hash is calculated using all the given pieces.
 * To calculate the hash call @c hash_compute().
 *
 * @param  ctx       Pointer to the hash context of this op.
 * @param  pkt       Structure holding the input.

 * @return 0 on success, negative errno code on fail.
 */
static inline int hash_update(struct hash_ctx *ctx, struct hash_pkt *pkt)
{
	pkt->ctx = ctx;

	return ctx->hash_hndlr(ctx, pkt, false);
}

/**
 * @}
 */

#endif /* ZEPHYR_INCLUDE_CRYPTO_H_ */
