162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/* Common header for Virtio crypto device.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright 2016 HUAWEI TECHNOLOGIES CO., LTD.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef _VIRTIO_CRYPTO_COMMON_H
862306a36Sopenharmony_ci#define _VIRTIO_CRYPTO_COMMON_H
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/virtio.h>
1162306a36Sopenharmony_ci#include <linux/crypto.h>
1262306a36Sopenharmony_ci#include <linux/spinlock.h>
1362306a36Sopenharmony_ci#include <linux/interrupt.h>
1462306a36Sopenharmony_ci#include <crypto/aead.h>
1562306a36Sopenharmony_ci#include <crypto/aes.h>
1662306a36Sopenharmony_ci#include <crypto/engine.h>
1762306a36Sopenharmony_ci#include <uapi/linux/virtio_crypto.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/* Internal representation of a data virtqueue */
2162306a36Sopenharmony_cistruct data_queue {
2262306a36Sopenharmony_ci	/* Virtqueue associated with this send _queue */
2362306a36Sopenharmony_ci	struct virtqueue *vq;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	/* To protect the vq operations for the dataq */
2662306a36Sopenharmony_ci	spinlock_t lock;
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	/* Name of the tx queue: dataq.$index */
2962306a36Sopenharmony_ci	char name[32];
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	struct crypto_engine *engine;
3262306a36Sopenharmony_ci	struct tasklet_struct done_task;
3362306a36Sopenharmony_ci};
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistruct virtio_crypto {
3662306a36Sopenharmony_ci	struct virtio_device *vdev;
3762306a36Sopenharmony_ci	struct virtqueue *ctrl_vq;
3862306a36Sopenharmony_ci	struct data_queue *data_vq;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	/* Work struct for config space updates */
4162306a36Sopenharmony_ci	struct work_struct config_work;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	/* To protect the vq operations for the controlq */
4462306a36Sopenharmony_ci	spinlock_t ctrl_lock;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	/* Maximum of data queues supported by the device */
4762306a36Sopenharmony_ci	u32 max_data_queues;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	/* Number of queue currently used by the driver */
5062306a36Sopenharmony_ci	u32 curr_queue;
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	/*
5362306a36Sopenharmony_ci	 * Specifies the services mask which the device support,
5462306a36Sopenharmony_ci	 * see VIRTIO_CRYPTO_SERVICE_*
5562306a36Sopenharmony_ci	 */
5662306a36Sopenharmony_ci	u32 crypto_services;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	/* Detailed algorithms mask */
5962306a36Sopenharmony_ci	u32 cipher_algo_l;
6062306a36Sopenharmony_ci	u32 cipher_algo_h;
6162306a36Sopenharmony_ci	u32 hash_algo;
6262306a36Sopenharmony_ci	u32 mac_algo_l;
6362306a36Sopenharmony_ci	u32 mac_algo_h;
6462306a36Sopenharmony_ci	u32 aead_algo;
6562306a36Sopenharmony_ci	u32 akcipher_algo;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	/* Maximum length of cipher key */
6862306a36Sopenharmony_ci	u32 max_cipher_key_len;
6962306a36Sopenharmony_ci	/* Maximum length of authenticated key */
7062306a36Sopenharmony_ci	u32 max_auth_key_len;
7162306a36Sopenharmony_ci	/* Maximum size of per request */
7262306a36Sopenharmony_ci	u64 max_size;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	unsigned long status;
7562306a36Sopenharmony_ci	atomic_t ref_count;
7662306a36Sopenharmony_ci	struct list_head list;
7762306a36Sopenharmony_ci	struct module *owner;
7862306a36Sopenharmony_ci	uint8_t dev_id;
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	/* Does the affinity hint is set for virtqueues? */
8162306a36Sopenharmony_ci	bool affinity_hint_set;
8262306a36Sopenharmony_ci};
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_cistruct virtio_crypto_sym_session_info {
8562306a36Sopenharmony_ci	/* Backend session id, which come from the host side */
8662306a36Sopenharmony_ci	__u64 session_id;
8762306a36Sopenharmony_ci};
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/*
9062306a36Sopenharmony_ci * Note: there are padding fields in request, clear them to zero before
9162306a36Sopenharmony_ci *       sending to host to avoid to divulge any information.
9262306a36Sopenharmony_ci * Ex, virtio_crypto_ctrl_request::ctrl::u::destroy_session::padding[48]
9362306a36Sopenharmony_ci */
9462306a36Sopenharmony_cistruct virtio_crypto_ctrl_request {
9562306a36Sopenharmony_ci	struct virtio_crypto_op_ctrl_req ctrl;
9662306a36Sopenharmony_ci	struct virtio_crypto_session_input input;
9762306a36Sopenharmony_ci	struct virtio_crypto_inhdr ctrl_status;
9862306a36Sopenharmony_ci	struct completion compl;
9962306a36Sopenharmony_ci};
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_cistruct virtio_crypto_request;
10262306a36Sopenharmony_citypedef void (*virtio_crypto_data_callback)
10362306a36Sopenharmony_ci		(struct virtio_crypto_request *vc_req, int len);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_cistruct virtio_crypto_request {
10662306a36Sopenharmony_ci	uint8_t status;
10762306a36Sopenharmony_ci	struct virtio_crypto_op_data_req *req_data;
10862306a36Sopenharmony_ci	struct scatterlist **sgs;
10962306a36Sopenharmony_ci	struct data_queue *dataq;
11062306a36Sopenharmony_ci	virtio_crypto_data_callback alg_cb;
11162306a36Sopenharmony_ci};
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ciint virtcrypto_devmgr_add_dev(struct virtio_crypto *vcrypto_dev);
11462306a36Sopenharmony_cistruct list_head *virtcrypto_devmgr_get_head(void);
11562306a36Sopenharmony_civoid virtcrypto_devmgr_rm_dev(struct virtio_crypto *vcrypto_dev);
11662306a36Sopenharmony_cistruct virtio_crypto *virtcrypto_devmgr_get_first(void);
11762306a36Sopenharmony_ciint virtcrypto_dev_in_use(struct virtio_crypto *vcrypto_dev);
11862306a36Sopenharmony_ciint virtcrypto_dev_get(struct virtio_crypto *vcrypto_dev);
11962306a36Sopenharmony_civoid virtcrypto_dev_put(struct virtio_crypto *vcrypto_dev);
12062306a36Sopenharmony_ciint virtcrypto_dev_started(struct virtio_crypto *vcrypto_dev);
12162306a36Sopenharmony_cibool virtcrypto_algo_is_supported(struct virtio_crypto *vcrypto_dev,
12262306a36Sopenharmony_ci				  uint32_t service,
12362306a36Sopenharmony_ci				  uint32_t algo);
12462306a36Sopenharmony_cistruct virtio_crypto *virtcrypto_get_dev_node(int node,
12562306a36Sopenharmony_ci					      uint32_t service,
12662306a36Sopenharmony_ci					      uint32_t algo);
12762306a36Sopenharmony_ciint virtcrypto_dev_start(struct virtio_crypto *vcrypto);
12862306a36Sopenharmony_civoid virtcrypto_dev_stop(struct virtio_crypto *vcrypto);
12962306a36Sopenharmony_ciint virtio_crypto_skcipher_crypt_req(
13062306a36Sopenharmony_ci	struct crypto_engine *engine, void *vreq);
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_civoid
13362306a36Sopenharmony_civirtcrypto_clear_request(struct virtio_crypto_request *vc_req);
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic inline int virtio_crypto_get_current_node(void)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	int cpu, node;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	cpu = get_cpu();
14062306a36Sopenharmony_ci	node = topology_physical_package_id(cpu);
14162306a36Sopenharmony_ci	put_cpu();
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	return node;
14462306a36Sopenharmony_ci}
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ciint virtio_crypto_skcipher_algs_register(struct virtio_crypto *vcrypto);
14762306a36Sopenharmony_civoid virtio_crypto_skcipher_algs_unregister(struct virtio_crypto *vcrypto);
14862306a36Sopenharmony_ciint virtio_crypto_akcipher_algs_register(struct virtio_crypto *vcrypto);
14962306a36Sopenharmony_civoid virtio_crypto_akcipher_algs_unregister(struct virtio_crypto *vcrypto);
15062306a36Sopenharmony_ciint virtio_crypto_ctrl_vq_request(struct virtio_crypto *vcrypto, struct scatterlist *sgs[],
15162306a36Sopenharmony_ci				  unsigned int out_sgs, unsigned int in_sgs,
15262306a36Sopenharmony_ci				  struct virtio_crypto_ctrl_request *vc_ctrl_req);
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci#endif /* _VIRTIO_CRYPTO_COMMON_H */
155