xref: /linux/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c (revision 570f7e331f5febb30f1384817463c7e42b65ca7d)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2  /* Algorithms supported by virtio crypto device
3   *
4   * Authors: Gonglei <arei.gonglei@huawei.com>
5   *
6   * Copyright 2016 HUAWEI TECHNOLOGIES CO., LTD.
7   */
8 
9 #include <crypto/engine.h>
10 #include <crypto/internal/skcipher.h>
11 #include <crypto/scatterwalk.h>
12 #include <linux/err.h>
13 #include <linux/scatterlist.h>
14 #include <uapi/linux/virtio_crypto.h>
15 #include "virtio_crypto_common.h"
16 
17 
18 struct virtio_crypto_skcipher_ctx {
19 	struct virtio_crypto *vcrypto;
20 
21 	struct virtio_crypto_sym_session_info enc_sess_info;
22 	struct virtio_crypto_sym_session_info dec_sess_info;
23 };
24 
25 struct virtio_crypto_sym_request {
26 	struct virtio_crypto_request base;
27 
28 	/* Cipher or aead */
29 	uint32_t type;
30 	uint8_t *iv;
31 	/* Encryption? */
32 	bool encrypt;
33 };
34 
35 struct virtio_crypto_algo {
36 	uint32_t algonum;
37 	uint32_t service;
38 	unsigned int active_devs;
39 	struct skcipher_engine_alg algo;
40 };
41 
42 /*
43  * The algs_lock protects the below global virtio_crypto_active_devs
44  * and crypto algorithms registion.
45  */
46 static DEFINE_MUTEX(algs_lock);
47 static void virtio_crypto_skcipher_finalize_req(
48 	struct virtio_crypto_sym_request *vc_sym_req,
49 	struct skcipher_request *req,
50 	int err);
51 
52 static void virtio_crypto_dataq_sym_callback
53 		(struct virtio_crypto_request *vc_req, int len)
54 {
55 	struct virtio_crypto_sym_request *vc_sym_req =
56 		container_of(vc_req, struct virtio_crypto_sym_request, base);
57 	struct skcipher_request *ablk_req =
58 		container_of((void *)vc_sym_req, struct skcipher_request,
59 			     __ctx);
60 	int error;
61 
62 	/* Finish the encrypt or decrypt process */
63 	if (vc_sym_req->type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
64 		switch (vc_req->status) {
65 		case VIRTIO_CRYPTO_OK:
66 			error = 0;
67 			break;
68 		case VIRTIO_CRYPTO_INVSESS:
69 		case VIRTIO_CRYPTO_ERR:
70 			error = -EINVAL;
71 			break;
72 		case VIRTIO_CRYPTO_BADMSG:
73 			error = -EBADMSG;
74 			break;
75 		default:
76 			error = -EIO;
77 			break;
78 		}
79 		virtio_crypto_skcipher_finalize_req(vc_sym_req,
80 							ablk_req, error);
81 	}
82 }
83 
84 static u64 virtio_crypto_alg_sg_nents_length(struct scatterlist *sg)
85 {
86 	u64 total = 0;
87 
88 	for (total = 0; sg; sg = sg_next(sg))
89 		total += sg->length;
90 
91 	return total;
92 }
93 
94 static int
95 virtio_crypto_alg_validate_key(int key_len, uint32_t *alg)
96 {
97 	switch (key_len) {
98 	case AES_KEYSIZE_128:
99 	case AES_KEYSIZE_192:
100 	case AES_KEYSIZE_256:
101 		*alg = VIRTIO_CRYPTO_CIPHER_AES_CBC;
102 		break;
103 	default:
104 		return -EINVAL;
105 	}
106 	return 0;
107 }
108 
109 static int virtio_crypto_alg_skcipher_init_session(
110 		struct virtio_crypto_skcipher_ctx *ctx,
111 		uint32_t alg, const uint8_t *key,
112 		unsigned int keylen,
113 		int encrypt)
114 {
115 	struct scatterlist outhdr, key_sg, inhdr, *sgs[3];
116 	struct virtio_crypto *vcrypto = ctx->vcrypto;
117 	int op = encrypt ? VIRTIO_CRYPTO_OP_ENCRYPT : VIRTIO_CRYPTO_OP_DECRYPT;
118 	int err;
119 	unsigned int num_out = 0, num_in = 0;
120 	struct virtio_crypto_op_ctrl_req *ctrl;
121 	struct virtio_crypto_session_input *input;
122 	struct virtio_crypto_sym_create_session_req *sym_create_session;
123 	struct virtio_crypto_ctrl_request *vc_ctrl_req;
124 
125 	/*
126 	 * Avoid to do DMA from the stack, switch to using
127 	 * dynamically-allocated for the key
128 	 */
129 	uint8_t *cipher_key = kmemdup(key, keylen, GFP_ATOMIC);
130 
131 	if (!cipher_key)
132 		return -ENOMEM;
133 
134 	vc_ctrl_req = kzalloc_obj(*vc_ctrl_req);
135 	if (!vc_ctrl_req) {
136 		err = -ENOMEM;
137 		goto out;
138 	}
139 
140 	/* Pad ctrl header */
141 	ctrl = &vc_ctrl_req->ctrl;
142 	ctrl->header.opcode = cpu_to_le32(VIRTIO_CRYPTO_CIPHER_CREATE_SESSION);
143 	ctrl->header.algo = cpu_to_le32(alg);
144 	/* Set the default dataqueue id to 0 */
145 	ctrl->header.queue_id = 0;
146 
147 	input = &vc_ctrl_req->input;
148 	input->status = cpu_to_le32(VIRTIO_CRYPTO_ERR);
149 	/* Pad cipher's parameters */
150 	sym_create_session = &ctrl->u.sym_create_session;
151 	sym_create_session->op_type = cpu_to_le32(VIRTIO_CRYPTO_SYM_OP_CIPHER);
152 	sym_create_session->u.cipher.para.algo = ctrl->header.algo;
153 	sym_create_session->u.cipher.para.keylen = cpu_to_le32(keylen);
154 	sym_create_session->u.cipher.para.op = cpu_to_le32(op);
155 
156 	sg_init_one(&outhdr, ctrl, sizeof(*ctrl));
157 	sgs[num_out++] = &outhdr;
158 
159 	/* Set key */
160 	sg_init_one(&key_sg, cipher_key, keylen);
161 	sgs[num_out++] = &key_sg;
162 
163 	/* Return status and session id back */
164 	sg_init_one(&inhdr, input, sizeof(*input));
165 	sgs[num_out + num_in++] = &inhdr;
166 
167 	err = virtio_crypto_ctrl_vq_request(vcrypto, sgs, num_out, num_in, vc_ctrl_req);
168 	if (err < 0)
169 		goto out;
170 
171 	if (le32_to_cpu(input->status) != VIRTIO_CRYPTO_OK) {
172 		pr_err("virtio_crypto: Create session failed status: %u\n",
173 			le32_to_cpu(input->status));
174 		err = -EINVAL;
175 		goto out;
176 	}
177 
178 	if (encrypt)
179 		ctx->enc_sess_info.session_id = le64_to_cpu(input->session_id);
180 	else
181 		ctx->dec_sess_info.session_id = le64_to_cpu(input->session_id);
182 
183 	err = 0;
184 out:
185 	kfree(vc_ctrl_req);
186 	kfree_sensitive(cipher_key);
187 	return err;
188 }
189 
190 static int virtio_crypto_alg_skcipher_close_session(
191 		struct virtio_crypto_skcipher_ctx *ctx,
192 		int encrypt)
193 {
194 	struct scatterlist outhdr, status_sg, *sgs[2];
195 	struct virtio_crypto_destroy_session_req *destroy_session;
196 	struct virtio_crypto *vcrypto = ctx->vcrypto;
197 	int err;
198 	unsigned int num_out = 0, num_in = 0;
199 	struct virtio_crypto_op_ctrl_req *ctrl;
200 	struct virtio_crypto_inhdr *ctrl_status;
201 	struct virtio_crypto_ctrl_request *vc_ctrl_req;
202 
203 	vc_ctrl_req = kzalloc_obj(*vc_ctrl_req);
204 	if (!vc_ctrl_req)
205 		return -ENOMEM;
206 
207 	ctrl_status = &vc_ctrl_req->ctrl_status;
208 	ctrl_status->status = VIRTIO_CRYPTO_ERR;
209 	/* Pad ctrl header */
210 	ctrl = &vc_ctrl_req->ctrl;
211 	ctrl->header.opcode = cpu_to_le32(VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION);
212 	/* Set the default virtqueue id to 0 */
213 	ctrl->header.queue_id = 0;
214 
215 	destroy_session = &ctrl->u.destroy_session;
216 
217 	if (encrypt)
218 		destroy_session->session_id = cpu_to_le64(ctx->enc_sess_info.session_id);
219 	else
220 		destroy_session->session_id = cpu_to_le64(ctx->dec_sess_info.session_id);
221 
222 	sg_init_one(&outhdr, ctrl, sizeof(*ctrl));
223 	sgs[num_out++] = &outhdr;
224 
225 	/* Return status and session id back */
226 	sg_init_one(&status_sg, &ctrl_status->status, sizeof(ctrl_status->status));
227 	sgs[num_out + num_in++] = &status_sg;
228 
229 	err = virtio_crypto_ctrl_vq_request(vcrypto, sgs, num_out, num_in, vc_ctrl_req);
230 	if (err < 0)
231 		goto out;
232 
233 	if (ctrl_status->status != VIRTIO_CRYPTO_OK) {
234 		pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n",
235 			ctrl_status->status,
236 		       le64_to_cpu(destroy_session->session_id));
237 
238 		err = -EINVAL;
239 		goto out;
240 	}
241 
242 	err = 0;
243 out:
244 	kfree(vc_ctrl_req);
245 	return err;
246 }
247 
248 static int virtio_crypto_alg_skcipher_init_sessions(
249 		struct virtio_crypto_skcipher_ctx *ctx,
250 		const uint8_t *key, unsigned int keylen)
251 {
252 	uint32_t alg;
253 	int ret;
254 	struct virtio_crypto *vcrypto = ctx->vcrypto;
255 
256 	if (keylen > vcrypto->max_cipher_key_len) {
257 		pr_err("virtio_crypto: the key is too long\n");
258 		return -EINVAL;
259 	}
260 
261 	if (virtio_crypto_alg_validate_key(keylen, &alg))
262 		return -EINVAL;
263 
264 	/* Create encryption session */
265 	ret = virtio_crypto_alg_skcipher_init_session(ctx,
266 			alg, key, keylen, 1);
267 	if (ret)
268 		return ret;
269 	/* Create decryption session */
270 	ret = virtio_crypto_alg_skcipher_init_session(ctx,
271 			alg, key, keylen, 0);
272 	if (ret) {
273 		virtio_crypto_alg_skcipher_close_session(ctx, 1);
274 		return ret;
275 	}
276 	return 0;
277 }
278 
279 /* Note: kernel crypto API realization */
280 static int virtio_crypto_skcipher_setkey(struct crypto_skcipher *tfm,
281 					 const uint8_t *key,
282 					 unsigned int keylen)
283 {
284 	struct virtio_crypto_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
285 	uint32_t alg;
286 	int ret;
287 
288 	ret = virtio_crypto_alg_validate_key(keylen, &alg);
289 	if (ret)
290 		return ret;
291 
292 	if (!ctx->vcrypto) {
293 		/* New key */
294 		int node = virtio_crypto_get_current_node();
295 		struct virtio_crypto *vcrypto =
296 				      virtcrypto_get_dev_node(node,
297 				      VIRTIO_CRYPTO_SERVICE_CIPHER, alg);
298 		if (!vcrypto) {
299 			pr_err("virtio_crypto: Could not find a virtio device in the system or unsupported algo\n");
300 			return -ENODEV;
301 		}
302 
303 		ctx->vcrypto = vcrypto;
304 	} else {
305 		/* Rekeying, we should close the created sessions previously */
306 		virtio_crypto_alg_skcipher_close_session(ctx, 1);
307 		virtio_crypto_alg_skcipher_close_session(ctx, 0);
308 	}
309 
310 	ret = virtio_crypto_alg_skcipher_init_sessions(ctx, key, keylen);
311 	if (ret) {
312 		virtcrypto_dev_put(ctx->vcrypto);
313 		ctx->vcrypto = NULL;
314 
315 		return ret;
316 	}
317 
318 	return 0;
319 }
320 
321 static int
322 __virtio_crypto_skcipher_do_req(struct virtio_crypto_sym_request *vc_sym_req,
323 		struct skcipher_request *req,
324 		struct data_queue *data_vq)
325 {
326 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
327 	struct virtio_crypto_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
328 	struct virtio_crypto_request *vc_req = &vc_sym_req->base;
329 	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
330 	struct virtio_crypto *vcrypto = ctx->vcrypto;
331 	struct virtio_crypto_op_data_req *req_data;
332 	int src_nents, dst_nents;
333 	int err;
334 	unsigned long flags;
335 	struct scatterlist outhdr, iv_sg, status_sg, **sgs;
336 	u64 dst_len;
337 	unsigned int num_out = 0, num_in = 0;
338 	int sg_total;
339 	uint8_t *iv;
340 	struct scatterlist *sg;
341 
342 	src_nents = sg_nents_for_len(req->src, req->cryptlen);
343 	if (src_nents < 0) {
344 		pr_err("Invalid number of src SG.\n");
345 		return src_nents;
346 	}
347 
348 	dst_nents = sg_nents(req->dst);
349 
350 	pr_debug("virtio_crypto: Number of sgs (src_nents: %d, dst_nents: %d)\n",
351 			src_nents, dst_nents);
352 
353 	/* Why 3?  outhdr + iv + inhdr */
354 	sg_total = src_nents + dst_nents + 3;
355 	sgs = kcalloc_node(sg_total, sizeof(*sgs), GFP_KERNEL,
356 				dev_to_node(&vcrypto->vdev->dev));
357 	if (!sgs)
358 		return -ENOMEM;
359 
360 	req_data = kzalloc_node(sizeof(*req_data), GFP_KERNEL,
361 				dev_to_node(&vcrypto->vdev->dev));
362 	if (!req_data) {
363 		kfree(sgs);
364 		return -ENOMEM;
365 	}
366 
367 	vc_req->req_data = req_data;
368 	vc_sym_req->type = VIRTIO_CRYPTO_SYM_OP_CIPHER;
369 	/* Head of operation */
370 	if (vc_sym_req->encrypt) {
371 		req_data->header.session_id =
372 			cpu_to_le64(ctx->enc_sess_info.session_id);
373 		req_data->header.opcode =
374 			cpu_to_le32(VIRTIO_CRYPTO_CIPHER_ENCRYPT);
375 	} else {
376 		req_data->header.session_id =
377 			cpu_to_le64(ctx->dec_sess_info.session_id);
378 		req_data->header.opcode =
379 			cpu_to_le32(VIRTIO_CRYPTO_CIPHER_DECRYPT);
380 	}
381 	req_data->u.sym_req.op_type = cpu_to_le32(VIRTIO_CRYPTO_SYM_OP_CIPHER);
382 	req_data->u.sym_req.u.cipher.para.iv_len = cpu_to_le32(ivsize);
383 	req_data->u.sym_req.u.cipher.para.src_data_len =
384 			cpu_to_le32(req->cryptlen);
385 
386 	dst_len = virtio_crypto_alg_sg_nents_length(req->dst);
387 	if (unlikely(dst_len > U32_MAX)) {
388 		pr_err("virtio_crypto: The dst_len is beyond U32_MAX\n");
389 		err = -EINVAL;
390 		goto free;
391 	}
392 
393 	dst_len = min_t(unsigned int, req->cryptlen, dst_len);
394 	pr_debug("virtio_crypto: src_len: %u, dst_len: %llu\n",
395 			req->cryptlen, dst_len);
396 
397 	if (unlikely(req->cryptlen + dst_len + ivsize +
398 		sizeof(vc_req->status) > vcrypto->max_size)) {
399 		pr_err("virtio_crypto: The length is too big\n");
400 		err = -EINVAL;
401 		goto free;
402 	}
403 
404 	req_data->u.sym_req.u.cipher.para.dst_data_len =
405 			cpu_to_le32((uint32_t)dst_len);
406 
407 	/* Outhdr */
408 	sg_init_one(&outhdr, req_data, sizeof(*req_data));
409 	sgs[num_out++] = &outhdr;
410 
411 	/* IV */
412 
413 	/*
414 	 * Avoid to do DMA from the stack, switch to using
415 	 * dynamically-allocated for the IV
416 	 */
417 	iv = kzalloc_node(ivsize, GFP_ATOMIC,
418 				dev_to_node(&vcrypto->vdev->dev));
419 	if (!iv) {
420 		err = -ENOMEM;
421 		goto free;
422 	}
423 	memcpy(iv, req->iv, ivsize);
424 	if (!vc_sym_req->encrypt)
425 		scatterwalk_map_and_copy(req->iv, req->src,
426 					 req->cryptlen - AES_BLOCK_SIZE,
427 					 AES_BLOCK_SIZE, 0);
428 
429 	sg_init_one(&iv_sg, iv, ivsize);
430 	sgs[num_out++] = &iv_sg;
431 	vc_sym_req->iv = iv;
432 
433 	/* Source data */
434 	for (sg = req->src; src_nents; sg = sg_next(sg), src_nents--)
435 		sgs[num_out++] = sg;
436 
437 	/* Destination data */
438 	for (sg = req->dst; sg; sg = sg_next(sg))
439 		sgs[num_out + num_in++] = sg;
440 
441 	/* Status */
442 	sg_init_one(&status_sg, &vc_req->status, sizeof(vc_req->status));
443 	sgs[num_out + num_in++] = &status_sg;
444 
445 	vc_req->sgs = sgs;
446 
447 	spin_lock_irqsave(&data_vq->lock, flags);
448 	err = virtqueue_add_sgs(data_vq->vq, sgs, num_out,
449 				num_in, vc_req, GFP_ATOMIC);
450 	virtqueue_kick(data_vq->vq);
451 	spin_unlock_irqrestore(&data_vq->lock, flags);
452 	if (unlikely(err < 0))
453 		goto free_iv;
454 
455 	return 0;
456 
457 free_iv:
458 	kfree_sensitive(iv);
459 free:
460 	kfree_sensitive(req_data);
461 	kfree(sgs);
462 	return err;
463 }
464 
465 static int virtio_crypto_skcipher_encrypt(struct skcipher_request *req)
466 {
467 	struct crypto_skcipher *atfm = crypto_skcipher_reqtfm(req);
468 	struct virtio_crypto_skcipher_ctx *ctx = crypto_skcipher_ctx(atfm);
469 	struct virtio_crypto_sym_request *vc_sym_req =
470 				skcipher_request_ctx(req);
471 	struct virtio_crypto_request *vc_req = &vc_sym_req->base;
472 	struct virtio_crypto *vcrypto = ctx->vcrypto;
473 	/* Use the first data virtqueue as default */
474 	struct data_queue *data_vq = &vcrypto->data_vq[0];
475 
476 	if (!req->cryptlen)
477 		return 0;
478 	if (req->cryptlen % AES_BLOCK_SIZE)
479 		return -EINVAL;
480 
481 	vc_req->dataq = data_vq;
482 	vc_req->alg_cb = virtio_crypto_dataq_sym_callback;
483 	vc_sym_req->encrypt = true;
484 
485 	return crypto_transfer_skcipher_request_to_engine(data_vq->engine, req);
486 }
487 
488 static int virtio_crypto_skcipher_decrypt(struct skcipher_request *req)
489 {
490 	struct crypto_skcipher *atfm = crypto_skcipher_reqtfm(req);
491 	struct virtio_crypto_skcipher_ctx *ctx = crypto_skcipher_ctx(atfm);
492 	struct virtio_crypto_sym_request *vc_sym_req =
493 				skcipher_request_ctx(req);
494 	struct virtio_crypto_request *vc_req = &vc_sym_req->base;
495 	struct virtio_crypto *vcrypto = ctx->vcrypto;
496 	/* Use the first data virtqueue as default */
497 	struct data_queue *data_vq = &vcrypto->data_vq[0];
498 
499 	if (!req->cryptlen)
500 		return 0;
501 	if (req->cryptlen % AES_BLOCK_SIZE)
502 		return -EINVAL;
503 
504 	vc_req->dataq = data_vq;
505 	vc_req->alg_cb = virtio_crypto_dataq_sym_callback;
506 	vc_sym_req->encrypt = false;
507 
508 	return crypto_transfer_skcipher_request_to_engine(data_vq->engine, req);
509 }
510 
511 static int virtio_crypto_skcipher_init(struct crypto_skcipher *tfm)
512 {
513 	crypto_skcipher_set_reqsize(tfm, sizeof(struct virtio_crypto_sym_request));
514 
515 	return 0;
516 }
517 
518 static void virtio_crypto_skcipher_exit(struct crypto_skcipher *tfm)
519 {
520 	struct virtio_crypto_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
521 
522 	if (!ctx->vcrypto)
523 		return;
524 
525 	virtio_crypto_alg_skcipher_close_session(ctx, 1);
526 	virtio_crypto_alg_skcipher_close_session(ctx, 0);
527 	virtcrypto_dev_put(ctx->vcrypto);
528 	ctx->vcrypto = NULL;
529 }
530 
531 int virtio_crypto_skcipher_crypt_req(
532 	struct crypto_engine *engine, void *vreq)
533 {
534 	struct skcipher_request *req = container_of(vreq, struct skcipher_request, base);
535 	struct virtio_crypto_sym_request *vc_sym_req =
536 				skcipher_request_ctx(req);
537 	struct virtio_crypto_request *vc_req = &vc_sym_req->base;
538 	struct data_queue *data_vq = vc_req->dataq;
539 	int ret;
540 
541 	ret = __virtio_crypto_skcipher_do_req(vc_sym_req, req, data_vq);
542 	if (ret < 0)
543 		return ret;
544 
545 	return 0;
546 }
547 
548 static void virtio_crypto_skcipher_finalize_req(
549 	struct virtio_crypto_sym_request *vc_sym_req,
550 	struct skcipher_request *req,
551 	int err)
552 {
553 	if (vc_sym_req->encrypt)
554 		scatterwalk_map_and_copy(req->iv, req->dst,
555 					 req->cryptlen - AES_BLOCK_SIZE,
556 					 AES_BLOCK_SIZE, 0);
557 	kfree_sensitive(vc_sym_req->iv);
558 	virtcrypto_clear_request(&vc_sym_req->base);
559 
560 	crypto_finalize_skcipher_request(vc_sym_req->base.dataq->engine,
561 					   req, err);
562 }
563 
564 static struct virtio_crypto_algo virtio_crypto_algs[] = { {
565 	.algonum = VIRTIO_CRYPTO_CIPHER_AES_CBC,
566 	.service = VIRTIO_CRYPTO_SERVICE_CIPHER,
567 	.algo.base = {
568 		.base.cra_name		= "cbc(aes)",
569 		.base.cra_driver_name	= "virtio_crypto_aes_cbc",
570 		.base.cra_priority	= 150,
571 		.base.cra_flags		= CRYPTO_ALG_ASYNC |
572 					  CRYPTO_ALG_ALLOCATES_MEMORY,
573 		.base.cra_blocksize	= AES_BLOCK_SIZE,
574 		.base.cra_ctxsize	= sizeof(struct virtio_crypto_skcipher_ctx),
575 		.base.cra_module	= THIS_MODULE,
576 		.init			= virtio_crypto_skcipher_init,
577 		.exit			= virtio_crypto_skcipher_exit,
578 		.setkey			= virtio_crypto_skcipher_setkey,
579 		.decrypt		= virtio_crypto_skcipher_decrypt,
580 		.encrypt		= virtio_crypto_skcipher_encrypt,
581 		.min_keysize		= AES_MIN_KEY_SIZE,
582 		.max_keysize		= AES_MAX_KEY_SIZE,
583 		.ivsize			= AES_BLOCK_SIZE,
584 	},
585 	.algo.op = {
586 		.do_one_request = virtio_crypto_skcipher_crypt_req,
587 	},
588 } };
589 
590 int virtio_crypto_skcipher_algs_register(struct virtio_crypto *vcrypto)
591 {
592 	int ret = 0;
593 	int i = 0;
594 
595 	mutex_lock(&algs_lock);
596 
597 	for (i = 0; i < ARRAY_SIZE(virtio_crypto_algs); i++) {
598 
599 		uint32_t service = virtio_crypto_algs[i].service;
600 		uint32_t algonum = virtio_crypto_algs[i].algonum;
601 
602 		if (!virtcrypto_algo_is_supported(vcrypto, service, algonum))
603 			continue;
604 
605 		if (virtio_crypto_algs[i].active_devs == 0) {
606 			ret = crypto_engine_register_skcipher(&virtio_crypto_algs[i].algo);
607 			if (ret)
608 				goto unlock;
609 		}
610 
611 		virtio_crypto_algs[i].active_devs++;
612 		dev_info(&vcrypto->vdev->dev, "Registered algo %s\n",
613 			 virtio_crypto_algs[i].algo.base.base.cra_name);
614 	}
615 
616 unlock:
617 	mutex_unlock(&algs_lock);
618 	return ret;
619 }
620 
621 void virtio_crypto_skcipher_algs_unregister(struct virtio_crypto *vcrypto)
622 {
623 	int i = 0;
624 
625 	mutex_lock(&algs_lock);
626 
627 	for (i = 0; i < ARRAY_SIZE(virtio_crypto_algs); i++) {
628 
629 		uint32_t service = virtio_crypto_algs[i].service;
630 		uint32_t algonum = virtio_crypto_algs[i].algonum;
631 
632 		if (virtio_crypto_algs[i].active_devs == 0 ||
633 		    !virtcrypto_algo_is_supported(vcrypto, service, algonum))
634 			continue;
635 
636 		if (virtio_crypto_algs[i].active_devs == 1)
637 			crypto_engine_unregister_skcipher(&virtio_crypto_algs[i].algo);
638 
639 		virtio_crypto_algs[i].active_devs--;
640 	}
641 
642 	mutex_unlock(&algs_lock);
643 }
644