drivers/crypto/virtio/virtio_crypto_akcipher_algs.c

Source file repositories/reference/linux-study-clean/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/virtio/virtio_crypto_akcipher_algs.c
Extension
.c
Size
16368 bytes
Lines
568
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct virtio_crypto_rsa_ctx {
	unsigned int key_size;
};

struct virtio_crypto_akcipher_ctx {
	struct virtio_crypto *vcrypto;
	bool session_valid;
	__u64 session_id;
	union {
		struct virtio_crypto_rsa_ctx rsa_ctx;
	};
};

struct virtio_crypto_akcipher_request {
	struct virtio_crypto_request base;
	void *src_buf;
	void *dst_buf;
	uint32_t opcode;
};

struct virtio_crypto_akcipher_algo {
	uint32_t algonum;
	uint32_t service;
	unsigned int active_devs;
	struct akcipher_engine_alg algo;
};

static DEFINE_MUTEX(algs_lock);

static void virtio_crypto_akcipher_finalize_req(
	struct virtio_crypto_akcipher_request *vc_akcipher_req,
	struct akcipher_request *req, int err)
{
	kfree(vc_akcipher_req->src_buf);
	kfree(vc_akcipher_req->dst_buf);
	vc_akcipher_req->src_buf = NULL;
	vc_akcipher_req->dst_buf = NULL;
	virtcrypto_clear_request(&vc_akcipher_req->base);

	crypto_finalize_akcipher_request(vc_akcipher_req->base.dataq->engine, req, err);
}

static void virtio_crypto_dataq_akcipher_callback(struct virtio_crypto_request *vc_req, int len)
{
	struct virtio_crypto_akcipher_request *vc_akcipher_req =
		container_of(vc_req, struct virtio_crypto_akcipher_request, base);
	struct akcipher_request *akcipher_req =
		container_of((void *)vc_akcipher_req, struct akcipher_request,
			     __ctx);
	int error;

	switch (vc_req->status) {
	case VIRTIO_CRYPTO_OK:
		error = 0;
		break;
	case VIRTIO_CRYPTO_INVSESS:
	case VIRTIO_CRYPTO_ERR:
		error = -EINVAL;
		break;
	case VIRTIO_CRYPTO_BADMSG:
		error = -EBADMSG;
		break;
	default:
		error = -EIO;
		break;
	}

	/* actual length may be less than dst buffer */
	akcipher_req->dst_len = len - sizeof(vc_req->status);
	sg_copy_from_buffer(akcipher_req->dst, sg_nents(akcipher_req->dst),
			    vc_akcipher_req->dst_buf, akcipher_req->dst_len);
	virtio_crypto_akcipher_finalize_req(vc_akcipher_req, akcipher_req, error);
}

static int virtio_crypto_alg_akcipher_init_session(struct virtio_crypto_akcipher_ctx *ctx,
		struct virtio_crypto_ctrl_header *header,
		struct virtio_crypto_akcipher_session_para *para,
		const uint8_t *key, unsigned int keylen)
{
	struct scatterlist outhdr_sg, key_sg, inhdr_sg, *sgs[3];
	struct virtio_crypto *vcrypto = ctx->vcrypto;
	uint8_t *pkey;
	int err;
	unsigned int num_out = 0, num_in = 0;
	struct virtio_crypto_op_ctrl_req *ctrl;
	struct virtio_crypto_session_input *input;
	struct virtio_crypto_ctrl_request *vc_ctrl_req;

	pkey = kmemdup(key, keylen, GFP_KERNEL);
	if (!pkey)

Annotation

Implementation Notes