linux/drivers/crypto/intel/keembay/keembay-ocs-ecc.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Intel Keem Bay OCS ECC Crypto Driver.
 *
 * Copyright (C) 2019-2021 Intel Corporation
 */

#define pr_fmt(fmt)

#include <crypto/ecc_curve.h>
#include <crypto/ecdh.h>
#include <crypto/engine.h>
#include <crypto/internal/ecc.h>
#include <crypto/internal/kpp.h>
#include <crypto/kpp.h>
#include <crypto/rng.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/fips.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/string.h>

#define DRV_NAME

#define KMB_OCS_ECC_PRIORITY

#define HW_OFFS_OCS_ECC_COMMAND
#define HW_OFFS_OCS_ECC_STATUS
#define HW_OFFS_OCS_ECC_DATA_IN
#define HW_OFFS_OCS_ECC_CX_DATA_OUT
#define HW_OFFS_OCS_ECC_CY_DATA_OUT
#define HW_OFFS_OCS_ECC_ISR
#define HW_OFFS_OCS_ECC_IER

#define HW_OCS_ECC_ISR_INT_STATUS_DONE
#define HW_OCS_ECC_COMMAND_INS_BP

#define HW_OCS_ECC_COMMAND_START_VAL

#define OCS_ECC_OP_SIZE_384
#define OCS_ECC_OP_SIZE_256

/* ECC Instruction : for ECC_COMMAND */
#define OCS_ECC_INST_WRITE_AX
#define OCS_ECC_INST_WRITE_AY
#define OCS_ECC_INST_WRITE_BX_D
#define OCS_ECC_INST_WRITE_BY_L
#define OCS_ECC_INST_WRITE_P
#define OCS_ECC_INST_WRITE_A
#define OCS_ECC_INST_CALC_D_IDX_A
#define OCS_ECC_INST_CALC_A_POW_B_MODP
#define OCS_ECC_INST_CALC_A_MUL_B_MODP
#define OCS_ECC_INST_CALC_A_ADD_B_MODP

#define ECC_ENABLE_INTR

#define POLL_USEC
#define TIMEOUT_USEC

#define KMB_ECC_VLI_MAX_DIGITS
#define KMB_ECC_VLI_MAX_BYTES

#define POW_CUBE

/**
 * struct ocs_ecc_dev - ECC device context
 * @list: List of device contexts
 * @dev: OCS ECC device
 * @base_reg: IO base address of OCS ECC
 * @engine: Crypto engine for the device
 * @irq_done: IRQ done completion.
 * @irq: IRQ number
 */
struct ocs_ecc_dev {};

/**
 * struct ocs_ecc_ctx - Transformation context.
 * @ecc_dev:	 The ECC driver associated with this context.
 * @curve:	 The elliptic curve used by this transformation.
 * @private_key: The private key.
 */
struct ocs_ecc_ctx {};

/* Driver data. */
struct ocs_ecc_drv {};

/* Global variable holding the list of OCS ECC devices (only one expected). */
static struct ocs_ecc_drv ocs_ecc =;

/* Get OCS ECC tfm context from kpp_request. */
static inline struct ocs_ecc_ctx *kmb_ocs_ecc_tctx(struct kpp_request *req)
{}

/* Converts number of digits to number of bytes. */
static inline unsigned int digits_to_bytes(unsigned int n)
{}

/*
 * Wait for ECC idle i.e when an operation (other than write operations)
 * is done.
 */
static inline int ocs_ecc_wait_idle(struct ocs_ecc_dev *dev)
{}

static void ocs_ecc_cmd_start(struct ocs_ecc_dev *ecc_dev, u32 op_size)
{}

/* Direct write of u32 buffer to ECC engine with associated instruction. */
static void ocs_ecc_write_cmd_and_data(struct ocs_ecc_dev *dev,
				       u32 op_size,
				       u32 inst,
				       const void *data_in,
				       size_t data_size)
{}

/* Start OCS ECC operation and wait for its completion. */
static int ocs_ecc_trigger_op(struct ocs_ecc_dev *ecc_dev, u32 op_size,
			      u32 inst)
{}

/**
 * ocs_ecc_read_cx_out() - Read the CX data output buffer.
 * @dev:	The OCS ECC device to read from.
 * @cx_out:	The buffer where to store the CX value. Must be at least
 *		@byte_count byte long.
 * @byte_count:	The amount of data to read.
 */
static inline void ocs_ecc_read_cx_out(struct ocs_ecc_dev *dev, void *cx_out,
				       size_t byte_count)
{}

/**
 * ocs_ecc_read_cy_out() - Read the CX data output buffer.
 * @dev:	The OCS ECC device to read from.
 * @cy_out:	The buffer where to store the CY value. Must be at least
 *		@byte_count byte long.
 * @byte_count:	The amount of data to read.
 */
static inline void ocs_ecc_read_cy_out(struct ocs_ecc_dev *dev, void *cy_out,
				       size_t byte_count)
{}

static struct ocs_ecc_dev *kmb_ocs_ecc_find_dev(struct ocs_ecc_ctx *tctx)
{}

/* Do point multiplication using OCS ECC HW. */
static int kmb_ecc_point_mult(struct ocs_ecc_dev *ecc_dev,
			      struct ecc_point *result,
			      const struct ecc_point *point,
			      u64 *scalar,
			      const struct ecc_curve *curve)
{}

/**
 * kmb_ecc_do_scalar_op() - Perform Scalar operation using OCS ECC HW.
 * @ecc_dev:	The OCS ECC device to use.
 * @scalar_out:	Where to store the output scalar.
 * @scalar_a:	Input scalar operand 'a'.
 * @scalar_b:	Input scalar operand 'b'
 * @curve:	The curve on which the operation is performed.
 * @ndigits:	The size of the operands (in digits).
 * @inst:	The operation to perform (as an OCS ECC instruction).
 *
 * Return:	0 on success, negative error code otherwise.
 */
static int kmb_ecc_do_scalar_op(struct ocs_ecc_dev *ecc_dev, u64 *scalar_out,
				const u64 *scalar_a, const u64 *scalar_b,
				const struct ecc_curve *curve,
				unsigned int ndigits, const u32 inst)
{}

/* SP800-56A section 5.6.2.3.4 partial verification: ephemeral keys only */
static int kmb_ocs_ecc_is_pubkey_valid_partial(struct ocs_ecc_dev *ecc_dev,
					       const struct ecc_curve *curve,
					       struct ecc_point *pk)
{}

/* SP800-56A section 5.6.2.3.3 full verification */
static int kmb_ocs_ecc_is_pubkey_valid_full(struct ocs_ecc_dev *ecc_dev,
					    const struct ecc_curve *curve,
					    struct ecc_point *pk)
{}

static int kmb_ecc_is_key_valid(const struct ecc_curve *curve,
				const u64 *private_key, size_t private_key_len)
{}

/*
 * ECC private keys are generated using the method of extra random bits,
 * equivalent to that described in FIPS 186-4, Appendix B.4.1.
 *
 * d = (c mod(n–1)) + 1    where c is a string of random bits, 64 bits longer
 *                         than requested
 * 0 <= c mod(n-1) <= n-2  and implies that
 * 1 <= d <= n-1
 *
 * This method generates a private key uniformly distributed in the range
 * [1, n-1].
 */
static int kmb_ecc_gen_privkey(const struct ecc_curve *curve, u64 *privkey)
{}

static int kmb_ocs_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
				   unsigned int len)
{}

/* Compute shared secret. */
static int kmb_ecc_do_shared_secret(struct ocs_ecc_ctx *tctx,
				    struct kpp_request *req)
{}

/* Compute public key. */
static int kmb_ecc_do_public_key(struct ocs_ecc_ctx *tctx,
				 struct kpp_request *req)
{}

static int kmb_ocs_ecc_do_one_request(struct crypto_engine *engine,
				      void *areq)
{}

static int kmb_ocs_ecdh_generate_public_key(struct kpp_request *req)
{}

static int kmb_ocs_ecdh_compute_shared_secret(struct kpp_request *req)
{}

static int kmb_ecc_tctx_init(struct ocs_ecc_ctx *tctx, unsigned int curve_id)
{}

static int kmb_ocs_ecdh_nist_p256_init_tfm(struct crypto_kpp *tfm)
{}

static int kmb_ocs_ecdh_nist_p384_init_tfm(struct crypto_kpp *tfm)
{}

static void kmb_ocs_ecdh_exit_tfm(struct crypto_kpp *tfm)
{}

static unsigned int kmb_ocs_ecdh_max_size(struct crypto_kpp *tfm)
{}

static struct kpp_engine_alg ocs_ecdh_p256 =;

static struct kpp_engine_alg ocs_ecdh_p384 =;

static irqreturn_t ocs_ecc_irq_handler(int irq, void *dev_id)
{}

static int kmb_ocs_ecc_probe(struct platform_device *pdev)
{}

static void kmb_ocs_ecc_remove(struct platform_device *pdev)
{}

/* Device tree driver match. */
static const struct of_device_id kmb_ocs_ecc_of_match[] =;

/* The OCS driver is a platform device. */
static struct platform_driver kmb_ocs_ecc_driver =;
module_platform_driver();

MODULE_LICENSE();
MODULE_DESCRIPTION();
MODULE_ALIAS_CRYPTO();
MODULE_ALIAS_CRYPTO();
MODULE_ALIAS_CRYPTO();
MODULE_ALIAS_CRYPTO();